python type and object @pycon.jp 2012

Download Python Type and Object @PyCon.JP 2012

If you can't read please download the document

Upload: hsinyi-chen

Post on 16-Apr-2017

5.807 views

Category:

Technology


1 download

TRANSCRIPT

Python Type And Object

(Chen Hsin-YI)

PyCon.JP 2012, 9/15, Japan

Who am I

a.k.a hychen

Software Engineer in Canonical Ltd.

Recently is interesting in programming language theory, functional programming

http://hychen.wuweig.org

http://about.me/hychen

I start to use Python since 2006?I choose to use Python is because Perl is too hard to me... And I also maintian 2 python module package10 Canonical , python...

Outline

Why I care?

Type Object and None-Type Object

Types create Classes

Subclassing a Class

Base Class Object

Subclassing a Type

Why?

I was interesting Python Object Model while I learn 'Meta Class Programming'

Meta Class is little bit of *Magic*

I was so confused on Type is Class's Class

Class is Type is Class

Bound or Unbound Method/Attributes? Oh! .

-> Enter: type.__new__(, MyClass, (,), {'__module__': '__main__', '__metaclass__': }) Enter: type.__init__(, MyClass, (,), {'__module__': '__main__', '__metaclass__': }) Enter: MyClass.__call__ --> Enter: MyClass.__new__(, , 1, 2, 3, {'k2': 2, 'k1': 1}) Enter: MyClass.__init__(, 1, 2, 3, {'k2': 2, 'k1': 1}) > getattr([], '__class__')

>>> type([])

[1,2] is an instance of type list

getattr a function to get a attribute from an object

type a function to get an object's type

Non-Type Object

Are instances of Types

Can not be subclassed.

Can not be instantiated.

Example

5 integer number

6.0 float number

hello! string

u Unicode

Type provides methods/attributes

>>> L = [1,2,3]>>> L.append(4)[1,2,3,4]>>> list

>>> list.append(L, 5)[1,2,3,4,5]

L.append is a bound method of list object L

list.append is a unbound method of type

You can think unbound method is a static method

Type provides methods/attributes

>>> 5 + 611>>> int

>>> int.__add__(5,6)11>>> add5 = getattr(5, '__add__')>>> add5(6)11

5 is a bound method of list object L

int.__add__ is a unbound method of type

+ operator does the same thing of '__add__' of

[1,2] + [3,4] has different meaning because [1,2] and [3,4]'s type is

Strong Type and Dynamic Type

+

>>> 5 + [1,2]Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for +: 'int' and 'list'

Python is Strong TypeType will not be convert to another type by interpreter

Python is Dynamic TypeThe type is created in runtime

class TypeError(StandardError) | Inappropriate argument type.

Type Object

- are objects- are used to represent abstract data types. - - - - ... - can be subclassed. (almost)- can be instantiated.

Type Object

Are also factory function to create their instance

>>> 5 is int(5)True>>> [1] is list(1)True>>> (1) is tuple(1)True

Built-in Types

>>> import types

>>> dir(types)

['BooleanType', 'BufferType', 'BuiltinFunctionType', 'BuiltinMethodType', 'ClassType', 'CodeType', 'ComplexType', 'DictProxyType', 'DictType', 'DictionaryType', 'EllipsisType', 'FileType', 'FloatType', 'FrameType', 'FunctionType', 'GeneratorType', 'GetSetDescriptorType', 'InstanceType', 'IntType', 'LambdaType', 'ListType', 'LongType', 'MemberDescriptorType', 'MethodType', 'ModuleType', 'NoneType', 'NotImplementedType', 'ObjectType', 'SliceType', 'StringType', 'StringTypes', 'TracebackType', 'TupleType', 'TypeType', 'UnboundMethodType', 'UnicodeType', 'XRangeType', '__builtins__', '__doc__', '__file__', '__name__', '__package__']

>>> types.IntType

If an object is an instance of ,then it is a type. Otherwise, it is not a type.

>>> type(list)

>>> type([])

Type Object or Non-Type?

Non-Type Object

Type Object

create

[ ]

create

Type Object

Type Object creates Type Object

Type Object

Type Object

creates

Type Object

Type Object

Type Object

creates

Type Object

Type Object

Type Object

creates

Type Object

Type Object

Type Object

creates

A Type Object of all Type Object

A function to get the type of an object

A function to create a new Class Object

Type creates Class

>>> myclass = type(class_name, base_classes, class_attrs)

>>>

new_classtype = the generated class

class_name = the name of new class, ex. "MyClass"

base_classes = A tuple of inherited classes of the class, ex. (, )

class_attrs = A dictionary of static methods/attributes of the class

__new__ and __init__

newtype = type.__new__(type, newtype_name, base_types, type_attrs)

type.__init__(newtype, newtype_name, base_type, type_attrs)

>>> cls = type.__new__(type, 'MyClass', (), {})>>> cls

>>> type.__init__(cls, 'MyClass', (), {})>>> >

Put it together

new_class = type.__call__(class_name, base_classes, class_attrs)

>>> type.__call__(type, 'MyClass', (), {})

>>> type('MyClass', (), {})

So far, we already understand how does a class be created.

Next, I will talk about subclassing

class MyClass(object): def __init__(self): pass

Subclassing a class

Base Class Object

>>> object.__class__('MyClass', (), {})

Class Name

Now, Let's talk about subclassing,Here you can see

class MyClass(object): __metaclass__ = TraceClassCreation

Subclassing a class with
a another type!

Change default type for tracing the class creation flow

Base Class Object

Class Name

>>> MyClass = TraceClassCreation('MyClass', (object, ), {})

Now, Let's talk about subclassing,Here you can see

-> Enter: type.__new__(, MyClass, (,), {'__module__': '__main__', '__metaclass__': }) Enter: type.__init__(, MyClass, (,), {'__module__': '__main__', '__metaclass__': }) Enter: MyClass.__call__ --> Enter: MyClass.__new__(, , 1, 2, 3, {'k2': 2, 'k1': 1}) Enter: MyClass.__init__(, 1, 2, 3, {'k2': 2, 'k1': 1}) Enter: MyClass.__new__(, , 1, 2, 3, {'k2': 2, 'k1': 1}) Enter: MyClass.__init__(, 1, 2, 3, {'k2': 2, 'k1': 1}) Enter: MyClass.__new__(, , 1, 2, 3, {'k2': 2, 'k1': 1}) Enter: MyClass.__init__(, 1, 2, 3, {'k2': 2, 'k1': 1}) > MyClass(1,2,3 , k1=1, k2=2)

-> Enter: type.__new__(, MyClass, (,), {'__module__': '__main__', '__metaclass__': }) Enter: type.__init__(, MyClass, (,), {'__module__': '__main__', '__metaclass__': }) Enter: MyClass.__call__ --> Enter: MyClass.__new__(, , 1, 2, 3, {'k2': 2, 'k1': 1}) Enter: MyClass.__init__(, 1, 2, 3, {'k2': 2, 'k1': 1})