python type and object @pycon.jp 2012
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})