Python Type and Object @PyCon.JP 2012

5,771 views

Published on

Published in: Technology, Sports
0 Comments
7 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
5,771
On SlideShare
0
From Embeds
0
Number of Embeds
3,630
Actions
Shares
0
Downloads
55
Comments
0
Likes
7
Embeds 0
No embeds

No notes for slide
  • 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 package 10 年開始在 Canonical 工作 , 但是主要的工作不是寫 python...
  • This the magic when you create an object which is the main Idea I will explain today! To understand the magic , I wrote a special type to track all phase in the object construction
  • Before we start, please keep this idea in mind, And forget any thing about Class you learn from other language , like C++, Java.
  • So far, we already understand how does a class be created. Next, I will talk about subclassing
  • Now, Let's talk about subclassing, Here you can see
  • Now, Let's talk about subclassing, Here you can see
  • In general programming , We only care about __init__ method of a Class only We don't care about __new__
  • dir(object) - __new__ and __init__ is defined in type object >>> type.__new__ >>> type.__init__ >>> int.__new__ >>> int.__init__
  • Demo [].__class is <type' list'> [].__class__.__base__ is <type 'object'>
  • Python 裡的物件其實分為 Type and Non-Type, Type 跟 Class 都是 Type Type 產生 class , class 產生物件 . 所以在 metaclass 在 python 裡指的是 type
  • Python Type and Object @PyCon.JP 2012

    1. 1. Python Type And Object 陳信屹 (Chen Hsin-YI) PyCon.JP 2012, 9/15, Japan
    2. 2. 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
    3. 3. Outline● Why I care?● Type Object and None-Type Object● Types create Classes● Subclassing a Class● Base Class Object● Subclassing a Type
    4. 4. 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 Classs Class ● Class is Type is Class ● Bound or Unbound Method/Attributes? Oh! ….
    5. 5. Type creates a Class creates a None-Type Object-> Enter: type.__new__(<class __main__.TraceClassCreation>,MyClass, (<type object>,), {__module__: __main__,__metaclass__: <class __main__.TraceClassCreation>})<- Return: <class __main__.MyClass> which is an instance of<class __main__.TraceClassCreation>-> Enter: type.__init__(<class __main__.MyClass>, MyClass,(<type object>,), {__module__: __main__, __metaclass__:<class __main__.TraceClassCreation>})<- Return: None-> Enter: MyClass.__call__ --> Enter: MyClass.__new__(<class __main__.MyClass>, <class__main__.MyClass>, 1, 2, 3, {k2: 2, k1: 1}) <-- Return: <__main__.MyClass object at 0x2512cd0> --> Enter: MyClass.__init__(<__main__.MyClass object at0x2512cd0>, 1, 2, 3, {k2: 2, k1: 1}) <-- Return: None<- Return: <__main__.MyClass object at 0x2512cd0> which is aninstance of <class __main__.MyClass>
    6. 6. 萬物皆物件Everything are objects
    7. 7. Type and Instance[1,2] is an instance of typelist>>> getattr([], __class__)<type list>>>> type([])<type list> getattr – a function to get a attribute from an object type – a function to get an objects type
    8. 8. 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
    9. 9. Type provides methods/attributes>>> L = [1,2,3] ● L.append is a bound>>> L.append(4) method of list object L[1,2,3,4] ● list.append is a unbound method of>>> list type <type list><type list> ● You can think>>> list.append(L, 5) unbound method is a static method[1,2,3,4,5]
    10. 10. Type provides methods/attributes>>> 5 + 6 ● 5 is a bound method of list object L ● int.__add__ is a unbound method of11 type <type int>>>> int ● + operator does the same thing of<type int> __add__ of <type int> ● [1,2] + [3,4] has different meaning>>> int.__add__(5,6) because [1,2] and [3,4]s type is11 <type list>>>> add5 = getattr(5, __add__)>>> add5(6)11
    11. 11. Strong Type and Dynamic Type<type int> + <type list> >>> 5 + [1,2] ● Python is Strong Type Traceback (most recent call last): ● Type will not be File "<stdin>", line 1, in <module> convert to another TypeError: unsupported operand type by interpreter type(s) for +: int and list ● Python is Dynamic Type class TypeError(StandardError) | Inappropriate argument type. ● The type is created in runtime
    12. 12. Type Object- are objects- are used to represent abstract data types. - <type int> - <type list> - <type str> - ...- can be subclassed. (almost)- can be instantiated.
    13. 13. Type ObjectAre also factory function to create their instance>>> 5 is int(5)True>>> [1] is list(1)True>>> (1) is tuple(1)True
    14. 14. 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 <type int>
    15. 15. Type Object or Non-Type? If an object is an instance of <type type>, then it is a type. Otherwise, it is not a type.>>> type(list) create<type type> Type Object Non-Type Object>>> type([]) create<type list> <type list> []
    16. 16. Type Object creates Type Object creates Type Object Type Object <type type> <type list> <type str> <type object> <type type> <class MyClass>
    17. 17. <type type>● A Type Object of all Type Object● A function to get the type of an object● A function to create a new Class Object
    18. 18. Type creates Class● >>> myclass = type(class_name, base_classes, class_attrs)● >>> <class __main__.MyClass> ● 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. (<type ● object>, ) ● class_attrs = A dictionary of static methods/attributes of the class
    19. 19. __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<class __main__.MyClass>>>> type.__init__(cls, MyClass, (), {})>>> >
    20. 20. Put it togethernew_class = type.__call__(class_name,base_classes, class_attrs)>>> type.__call__(type, MyClass, (), {})<class __main__.MyClass>>>> type(MyClass, (), {})<class __main__.MyClass>
    21. 21. Subclassing a class Base Class Object Class Nameclass MyClass(object): def __init__(self): >>> object.__class__(MyClass, (), {}) pass <class __main__.MyClass>
    22. 22. Subclassing a class with a another type! Class Name Base Class Object class MyClass(object): __metaclass__ = TraceClassCreation Change default type for tracing the class creation flow>>> MyClass = TraceClassCreation(MyClass, (object, ), {})
    23. 23. Type creates a Class creates a None-Type Object-> Enter: type.__new__(<class __main__.TraceClassCreation>,MyClass, (<type object>,), {__module__: __main__,__metaclass__: <class __main__.TraceClassCreation>})<- Return: <class __main__.MyClass> which is an instance of<class __main__.TraceClassCreation>-> Enter: type.__init__(<class __main__.MyClass>, MyClass,(<type object>,), {__module__: __main__, __metaclass__:<class __main__.TraceClassCreation>})<- Return: None-> Enter: MyClass.__call__ --> Enter: MyClass.__new__(<class __main__.MyClass>, <class__main__.MyClass>, 1, 2, 3, {k2: 2, k1: 1}) <-- Return: <__main__.MyClass object at 0x2512cd0> --> Enter: MyClass.__init__(<__main__.MyClass object at0x2512cd0>, 1, 2, 3, {k2: 2, k1: 1}) <-- Return: None<- Return: <__main__.MyClass object at 0x2512cd0> which is aninstance of <class __main__.MyClass>
    24. 24. Type creates a Class creates a None-Type Object-> Enter: type.__new__(<class __main__.TraceClassCreation>,MyClass, (<type object>,), {__module__: __main__,__metaclass__: <class __main__.TraceClassCreation>})<- Return: <class __main__.MyClass> which is an instance of<class __main__.TraceClassCreation>-> Enter: type.__init__(<class __main__.MyClass>, MyClass,(<type object>,), {__module__: __main__, __metaclass__:<class __main__.TraceClassCreation>})<- Return: None-> Enter: MyClass.__call__ --> Enter: MyClass.__new__(<class __main__.MyClass>, <class__main__.MyClass>, 1, 2, 3, {k2: 2, k1: 1}) <-- Return: <__main__.MyClass object at 0x2512cd0> --> Enter: MyClass.__init__(<__main__.MyClass object at0x2512cd0>, 1, 2, 3, {k2: 2, k1: 1}) <-- Return: None<- Return: <__main__.MyClass object at 0x2512cd0> which is aninstance of <class __main__.MyClass>
    25. 25. Type creates a Class creates a None-Type Object-> Enter: type.__new__(<class __main__.TraceClassCreation>,MyClass, (<type object>,), {__module__: __main__,__metaclass__: <class __main__.TraceClassCreation>}) >>> MyClass(1,2,3 , k1=1, k2=2)<- Return: <class __main__.MyClass> which is an instance of<class __main__.TraceClassCreation>-> <__main__.MyClass object at 0x2512cd0> Enter: type.__init__(<class __main__.MyClass>, MyClass,(<type object>,), {__module__: __main__, __metaclass__:<class __main__.TraceClassCreation>})<- Return: None-> Enter: MyClass.__call__ --> Enter: MyClass.__new__(<class __main__.MyClass>, <class__main__.MyClass>, 1, 2, 3, {k2: 2, k1: 1}) <-- Return: <__main__.MyClass object at 0x2512cd0> --> Enter: MyClass.__init__(<__main__.MyClass object at0x2512cd0>, 1, 2, 3, {k2: 2, k1: 1}) <-- Return: None<- Return: <__main__.MyClass object at 0x2512cd0> which is aninstance of <class __main__.MyClass>
    26. 26. Type creates a Class creates a None-Type Object-> Enter: type.__new__(<class __main__.TraceClassCreation>,MyClass, (<type object>,), {__module__: __main__,__metaclass__: <class __main__.TraceClassCreation>})<- Return: <class __main__.MyClass> which is an instance of<class __main__.TraceClassCreation>-> Enter: type.__init__(<class __main__.MyClass>, MyClass,(<type object>,), {__module__: __main__, __metaclass__:<class __main__.TraceClassCreation>})<- Return: None-> Enter: MyClass.__call__ --> Enter: MyClass.__new__(<class __main__.MyClass>, <class__main__.MyClass>, 1, 2, 3, {k2: 2, k1: 1}) <-- Return: <__main__.MyClass object at 0x2512cd0> --> Enter: MyClass.__init__(<__main__.MyClass object at0x2512cd0>, 1, 2, 3, {k2: 2, k1: 1}) <-- Return: None<- Return: <__main__.MyClass object at 0x2512cd0> which is aninstance of <class __main__.MyClass>
    27. 27. <type object>● Are base class object of all object● Defines basic methods and attributes of an base object● Even <type type> is an instance of <type object>● To know parent class of an object, we can check __base__ or __bases__ attributes of type of an object
    28. 28. <type object>isinstance(1, object) is Trueisinstance(, object) is Trueisinstance([], object) is Trueisinstance((), object) is Trueisinstance({}, object) is Trueisinstance(lambda e: e, object) is True
    29. 29. <type object>isinstance(object, object) is Trueisinstance(str, object) is Trueisinstance(list, object) is Trueisinstance(tuple, object) is Trueisinstance(dict, object) is Trueisinstance(types.FunctionType, object) is True
    30. 30. Base Object Tuple function(){}.prototype {}.prototypetype.__base__class.__base__
    31. 31. Subclasisng Typeclass MyType(type): def __new__(basetype, name, bases, dct): return type.__new__(basetype, name, bases, dct) def __init__(newclass, name, bases, dct): return type.__init__(newclass, name, bases, dct) def __call__(newclass, *args, **kwargs): obj = newclass.__new__(newclass) newclass.__init__(obj, *args, **kwargs) return obj
    32. 32. Subclassing Typeclass MyType(type): def __call__(newtype, newtype_name, newtype_bases, newtype_dict): print "Args: {}".format(args) print "Keyword Args: {}".format(kwargs) return None>> MyClass = MyType(MyClass, (), {})>> obj = MyClass()Args: (1, 2)Keyword Args: {foo: bar}None
    33. 33. Bound and UnboundInstance method/attributes is bound, its typesmethod attributes is unbound.obj = MyClass()new_value = obj.attr # obj.attr.__get__(obj,MyClass)obj.attr = new_value # obj.attr.__set__(obj,new_value)Reference : Descriptor HowTo Guide
    34. 34. Notes for Meta Class ProgrammingThese are unbound methods of Type Object● type.__new__● type.__call__These are unbound methods of Class Object● class.__new__
    35. 35. Notes for Meta Class ProgrammingThese are bound methods of Type Object● type.__init__These are bound methods of Class Object● class.__init__● class.__call__
    36. 36. Python Object MapPicture Source : http://www.cafepy.com/article/python_types_and_objects/python_types_and_objects.html
    37. 37. Type → None-Type ObjectType → Class → None-Type Object
    38. 38. Objects are instances of classes.Classes are instance of types.
    39. 39. <type object> is base class of all classes.<type type> is meta class of all classes.
    40. 40. Does this like JavaScript? :)Ref: COSCUP-2012 Python Object v.s. JavaScript Prototype
    41. 41. Reference• Article, PEP 253 , Guido van Rossum• Article, Python types and objects, Shalabh Chaturvedi• Slide, Meta Class Programming in Python, Juan-ManuelGimeno• Slide, Metaclass In Python, Guy Wiener• Metaclass programming in Python, IBM DeveloperWorld• Slide, What Meta Class can do for you?, Chen Hsin-Yi• Slide,Python Type-Based Class v.s. JavaScript Prototype,Chen Hsin-Yi• Article, Descriptor How-To Guide, Raymond Hettinger
    42. 42. Thanks謝謝聆聽
    43. 43. This slide is released underCreative Commons Attribution-ShareAlike 3.0 Taiwan License

    ×