Object-oriented Programming in Python

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    5 Favorites

    Object-oriented Programming in Python - Presentation Transcript

    1. Object Oriented Programming in Python Juan Manuel Gimeno Illa jmgimeno@diei.udl.cat Curs 2007-2008 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 1 / 49
    2. Outline 1 Introduction 2 Classes 3 Instances I 4 Descriptors Referencing Attributes Bound and Unbound Methods Properties Class-Level Methods 5 Inheritance Method Resolution Order Cooperative Superclasses 6 Instances II J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 2 / 49
    3. Introduction Programming Paradigms A programming paradigm consists in the basic concepts into which our programs are made of Procedural Modules, data structures and procedures that operate upon them Objectural Objects which encapsulate state and behaviour and messages passed between these objects Functional Functions and closures, recursion, lists, ... Python is a multiparadigm programming language this allows the programmer to choose the paradigm that best suits the problem this allows the program to mix paradigms this allows the program to evolve switching paradigm if necessary J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 3 / 49
    4. Introduction Programming Paradigms A programming paradigm consists in the basic concepts into which our programs are made of Procedural Modules, data structures and procedures that operate upon them Objectural Objects which encapsulate state and behaviour and messages passed between these objects Functional Functions and closures, recursion, lists, ... Python is a multiparadigm programming language this allows the programmer to choose the paradigm that best suits the problem this allows the program to mix paradigms this allows the program to evolve switching paradigm if necessary J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 3 / 49
    5. Introduction Programming Paradigms A programming paradigm consists in the basic concepts into which our programs are made of Procedural Modules, data structures and procedures that operate upon them Objectural Objects which encapsulate state and behaviour and messages passed between these objects Functional Functions and closures, recursion, lists, ... Python is a multiparadigm programming language this allows the programmer to choose the paradigm that best suits the problem this allows the program to mix paradigms this allows the program to evolve switching paradigm if necessary J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 3 / 49
    6. Introduction Programming Paradigms A programming paradigm consists in the basic concepts into which our programs are made of Procedural Modules, data structures and procedures that operate upon them Objectural Objects which encapsulate state and behaviour and messages passed between these objects Functional Functions and closures, recursion, lists, ... Python is a multiparadigm programming language this allows the programmer to choose the paradigm that best suits the problem this allows the program to mix paradigms this allows the program to evolve switching paradigm if necessary J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 3 / 49
    7. Introduction Programming Paradigms A programming paradigm consists in the basic concepts into which our programs are made of Procedural Modules, data structures and procedures that operate upon them Objectural Objects which encapsulate state and behaviour and messages passed between these objects Functional Functions and closures, recursion, lists, ... Python is a multiparadigm programming language this allows the programmer to choose the paradigm that best suits the problem this allows the program to mix paradigms this allows the program to evolve switching paradigm if necessary J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 3 / 49
    8. Introduction Programming Paradigms A programming paradigm consists in the basic concepts into which our programs are made of Procedural Modules, data structures and procedures that operate upon them Objectural Objects which encapsulate state and behaviour and messages passed between these objects Functional Functions and closures, recursion, lists, ... Python is a multiparadigm programming language this allows the programmer to choose the paradigm that best suits the problem this allows the program to mix paradigms this allows the program to evolve switching paradigm if necessary J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 3 / 49
    9. Introduction Programming Paradigms A programming paradigm consists in the basic concepts into which our programs are made of Procedural Modules, data structures and procedures that operate upon them Objectural Objects which encapsulate state and behaviour and messages passed between these objects Functional Functions and closures, recursion, lists, ... Python is a multiparadigm programming language this allows the programmer to choose the paradigm that best suits the problem this allows the program to mix paradigms this allows the program to evolve switching paradigm if necessary J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 3 / 49
    10. Introduction Programming Paradigms A programming paradigm consists in the basic concepts into which our programs are made of Procedural Modules, data structures and procedures that operate upon them Objectural Objects which encapsulate state and behaviour and messages passed between these objects Functional Functions and closures, recursion, lists, ... Python is a multiparadigm programming language this allows the programmer to choose the paradigm that best suits the problem this allows the program to mix paradigms this allows the program to evolve switching paradigm if necessary J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 3 / 49
    11. Classes Python classes A class is a python object with several characteristics: You can call a class as it where a function and this call returns a new instance of the class A class has arbitrary named attributes that can be bound, unbound an referenced The class attributes can be descriptors (including functions) or normal data objects Class attributes bound to functions are also known as methods A method can have special python-defined meaning (they’re named with two leading and trailing underscores) A class clan inherit from other classes, meaning it delegates to other classes the look-up of attributes that are not found in the class itself J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 4 / 49
    12. Classes Python classes A class is a python object with several characteristics: You can call a class as it where a function and this call returns a new instance of the class A class has arbitrary named attributes that can be bound, unbound an referenced The class attributes can be descriptors (including functions) or normal data objects Class attributes bound to functions are also known as methods A method can have special python-defined meaning (they’re named with two leading and trailing underscores) A class clan inherit from other classes, meaning it delegates to other classes the look-up of attributes that are not found in the class itself J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 4 / 49
    13. Classes Python classes A class is a python object with several characteristics: You can call a class as it where a function and this call returns a new instance of the class A class has arbitrary named attributes that can be bound, unbound an referenced The class attributes can be descriptors (including functions) or normal data objects Class attributes bound to functions are also known as methods A method can have special python-defined meaning (they’re named with two leading and trailing underscores) A class clan inherit from other classes, meaning it delegates to other classes the look-up of attributes that are not found in the class itself J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 4 / 49
    14. Classes Python classes A class is a python object with several characteristics: You can call a class as it where a function and this call returns a new instance of the class A class has arbitrary named attributes that can be bound, unbound an referenced The class attributes can be descriptors (including functions) or normal data objects Class attributes bound to functions are also known as methods A method can have special python-defined meaning (they’re named with two leading and trailing underscores) A class clan inherit from other classes, meaning it delegates to other classes the look-up of attributes that are not found in the class itself J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 4 / 49
    15. Classes Python classes A class is a python object with several characteristics: You can call a class as it where a function and this call returns a new instance of the class A class has arbitrary named attributes that can be bound, unbound an referenced The class attributes can be descriptors (including functions) or normal data objects Class attributes bound to functions are also known as methods A method can have special python-defined meaning (they’re named with two leading and trailing underscores) A class clan inherit from other classes, meaning it delegates to other classes the look-up of attributes that are not found in the class itself J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 4 / 49
    16. Classes Python classes A class is a python object with several characteristics: You can call a class as it where a function and this call returns a new instance of the class A class has arbitrary named attributes that can be bound, unbound an referenced The class attributes can be descriptors (including functions) or normal data objects Class attributes bound to functions are also known as methods A method can have special python-defined meaning (they’re named with two leading and trailing underscores) A class clan inherit from other classes, meaning it delegates to other classes the look-up of attributes that are not found in the class itself J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 4 / 49
    17. Classes Object models Since Python2.2 there co-exist two slightly different object models in the language Old-style (classic) classes This is the model existing prior to Python2.2 New-style classes This is the preferred model for new code Old-style New-style >>> class A: pass >>> class A(object): pass >>> class B: pass >>> class B(object): pass >>> a, b = A(), B() >>> a, b = A(), B() >>> type(a) == type(b) >>> type(a) == type(b) True False >>> type(a) >>> type(a) <type ’instance’> <class ’ main .A’> J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 5 / 49
    18. Classes Object models Since Python2.2 there co-exist two slightly different object models in the language Old-style (classic) classes This is the model existing prior to Python2.2 New-style classes This is the preferred model for new code Old-style New-style >>> class A: pass >>> class A(object): pass >>> class B: pass >>> class B(object): pass >>> a, b = A(), B() >>> a, b = A(), B() >>> type(a) == type(b) >>> type(a) == type(b) True False >>> type(a) >>> type(a) <type ’instance’> <class ’ main .A’> J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 5 / 49
    19. Classes Object models Since Python2.2 there co-exist two slightly different object models in the language Old-style (classic) classes This is the model existing prior to Python2.2 New-style classes This is the preferred model for new code Old-style New-style >>> class A: pass >>> class A(object): pass >>> class B: pass >>> class B(object): pass >>> a, b = A(), B() >>> a, b = A(), B() >>> type(a) == type(b) >>> type(a) == type(b) True False >>> type(a) >>> type(a) <type ’instance’> <class ’ main .A’> J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 5 / 49
    20. Classes Object models Since Python2.2 there co-exist two slightly different object models in the language Old-style (classic) classes This is the model existing prior to Python2.2 New-style classes This is the preferred model for new code Old-style New-style >>> class A: pass >>> class A(object): pass >>> class B: pass >>> class B(object): pass >>> a, b = A(), B() >>> a, b = A(), B() >>> type(a) == type(b) >>> type(a) == type(b) True False >>> type(a) >>> type(a) <type ’instance’> <class ’ main .A’> J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 5 / 49
    21. Classes Object models Since Python2.2 there co-exist two slightly different object models in the language Old-style (classic) classes This is the model existing prior to Python2.2 New-style classes This is the preferred model for new code Old-style New-style >>> class A: pass >>> class A(object): pass >>> class B: pass >>> class B(object): pass >>> a, b = A(), B() >>> a, b = A(), B() >>> type(a) == type(b) >>> type(a) == type(b) True False >>> type(a) >>> type(a) <type ’instance’> <class ’ main .A’> J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 5 / 49
    22. Classes New-style classes Defined in the type and class unification effort in python2.2 (Introduced without breaking backwards compatibility) Simpler, more regular and more powerful Built-in types (e.g. dict) can be subclassed Properties: attributes managed by get/set methods Static and class methods (via descriptor API) Cooperative classes (sane multiple inheritance) Meta-class programming It will be the default (and unique) in the future Documents: Unifying types and classes in Python 2.2 PEP-252: Making types look more like classes PEP-253: Subtyping built-in types J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 6 / 49
    23. Classes New-style classes Defined in the type and class unification effort in python2.2 (Introduced without breaking backwards compatibility) Simpler, more regular and more powerful Built-in types (e.g. dict) can be subclassed Properties: attributes managed by get/set methods Static and class methods (via descriptor API) Cooperative classes (sane multiple inheritance) Meta-class programming It will be the default (and unique) in the future Documents: Unifying types and classes in Python 2.2 PEP-252: Making types look more like classes PEP-253: Subtyping built-in types J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 6 / 49
    24. Classes New-style classes Defined in the type and class unification effort in python2.2 (Introduced without breaking backwards compatibility) Simpler, more regular and more powerful Built-in types (e.g. dict) can be subclassed Properties: attributes managed by get/set methods Static and class methods (via descriptor API) Cooperative classes (sane multiple inheritance) Meta-class programming It will be the default (and unique) in the future Documents: Unifying types and classes in Python 2.2 PEP-252: Making types look more like classes PEP-253: Subtyping built-in types J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 6 / 49
    25. Classes New-style classes Defined in the type and class unification effort in python2.2 (Introduced without breaking backwards compatibility) Simpler, more regular and more powerful Built-in types (e.g. dict) can be subclassed Properties: attributes managed by get/set methods Static and class methods (via descriptor API) Cooperative classes (sane multiple inheritance) Meta-class programming It will be the default (and unique) in the future Documents: Unifying types and classes in Python 2.2 PEP-252: Making types look more like classes PEP-253: Subtyping built-in types J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 6 / 49
    26. Classes New-style classes Defined in the type and class unification effort in python2.2 (Introduced without breaking backwards compatibility) Simpler, more regular and more powerful Built-in types (e.g. dict) can be subclassed Properties: attributes managed by get/set methods Static and class methods (via descriptor API) Cooperative classes (sane multiple inheritance) Meta-class programming It will be the default (and unique) in the future Documents: Unifying types and classes in Python 2.2 PEP-252: Making types look more like classes PEP-253: Subtyping built-in types J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 6 / 49
    27. Classes New-style classes Defined in the type and class unification effort in python2.2 (Introduced without breaking backwards compatibility) Simpler, more regular and more powerful Built-in types (e.g. dict) can be subclassed Properties: attributes managed by get/set methods Static and class methods (via descriptor API) Cooperative classes (sane multiple inheritance) Meta-class programming It will be the default (and unique) in the future Documents: Unifying types and classes in Python 2.2 PEP-252: Making types look more like classes PEP-253: Subtyping built-in types J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 6 / 49
    28. Classes New-style classes Defined in the type and class unification effort in python2.2 (Introduced without breaking backwards compatibility) Simpler, more regular and more powerful Built-in types (e.g. dict) can be subclassed Properties: attributes managed by get/set methods Static and class methods (via descriptor API) Cooperative classes (sane multiple inheritance) Meta-class programming It will be the default (and unique) in the future Documents: Unifying types and classes in Python 2.2 PEP-252: Making types look more like classes PEP-253: Subtyping built-in types J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 6 / 49
    29. Classes New-style classes Defined in the type and class unification effort in python2.2 (Introduced without breaking backwards compatibility) Simpler, more regular and more powerful Built-in types (e.g. dict) can be subclassed Properties: attributes managed by get/set methods Static and class methods (via descriptor API) Cooperative classes (sane multiple inheritance) Meta-class programming It will be the default (and unique) in the future Documents: Unifying types and classes in Python 2.2 PEP-252: Making types look more like classes PEP-253: Subtyping built-in types J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 6 / 49
    30. Classes New-style classes Defined in the type and class unification effort in python2.2 (Introduced without breaking backwards compatibility) Simpler, more regular and more powerful Built-in types (e.g. dict) can be subclassed Properties: attributes managed by get/set methods Static and class methods (via descriptor API) Cooperative classes (sane multiple inheritance) Meta-class programming It will be the default (and unique) in the future Documents: Unifying types and classes in Python 2.2 PEP-252: Making types look more like classes PEP-253: Subtyping built-in types J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 6 / 49
    31. Classes New-style classes Defined in the type and class unification effort in python2.2 (Introduced without breaking backwards compatibility) Simpler, more regular and more powerful Built-in types (e.g. dict) can be subclassed Properties: attributes managed by get/set methods Static and class methods (via descriptor API) Cooperative classes (sane multiple inheritance) Meta-class programming It will be the default (and unique) in the future Documents: Unifying types and classes in Python 2.2 PEP-252: Making types look more like classes PEP-253: Subtyping built-in types J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 6 / 49
    32. Classes New-style classes Defined in the type and class unification effort in python2.2 (Introduced without breaking backwards compatibility) Simpler, more regular and more powerful Built-in types (e.g. dict) can be subclassed Properties: attributes managed by get/set methods Static and class methods (via descriptor API) Cooperative classes (sane multiple inheritance) Meta-class programming It will be the default (and unique) in the future Documents: Unifying types and classes in Python 2.2 PEP-252: Making types look more like classes PEP-253: Subtyping built-in types J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 6 / 49
    33. Classes New-style classes Defined in the type and class unification effort in python2.2 (Introduced without breaking backwards compatibility) Simpler, more regular and more powerful Built-in types (e.g. dict) can be subclassed Properties: attributes managed by get/set methods Static and class methods (via descriptor API) Cooperative classes (sane multiple inheritance) Meta-class programming It will be the default (and unique) in the future Documents: Unifying types and classes in Python 2.2 PEP-252: Making types look more like classes PEP-253: Subtyping built-in types J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 6 / 49
    34. Classes New-style classes Defined in the type and class unification effort in python2.2 (Introduced without breaking backwards compatibility) Simpler, more regular and more powerful Built-in types (e.g. dict) can be subclassed Properties: attributes managed by get/set methods Static and class methods (via descriptor API) Cooperative classes (sane multiple inheritance) Meta-class programming It will be the default (and unique) in the future Documents: Unifying types and classes in Python 2.2 PEP-252: Making types look more like classes PEP-253: Subtyping built-in types J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 6 / 49
    35. Classes The class statement class classname(base-classes): statement(s) classname is a variable that gets (re)bound to the class object after the class statement finishes executing base-classes is a comma separated series of expressions whose values must be classes if it does not exists, the created class is old-style if all base-classes are old-style, the created class is old-style otherwise it is a new-style class1 since every type subclasses built-in object, we can use object to mark a class as new-style when no true bases exist The statements (a.k.a. the class body) define the set of class attributes which will be shared by all instances of the class 1 We are not considering metaclass now J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 7 / 49
    36. Classes The class statement class classname(base-classes): statement(s) classname is a variable that gets (re)bound to the class object after the class statement finishes executing base-classes is a comma separated series of expressions whose values must be classes if it does not exists, the created class is old-style if all base-classes are old-style, the created class is old-style otherwise it is a new-style class1 since every type subclasses built-in object, we can use object to mark a class as new-style when no true bases exist The statements (a.k.a. the class body) define the set of class attributes which will be shared by all instances of the class 1 We are not considering metaclass now J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 7 / 49
    37. Classes The class statement class classname(base-classes): statement(s) classname is a variable that gets (re)bound to the class object after the class statement finishes executing base-classes is a comma separated series of expressions whose values must be classes if it does not exists, the created class is old-style if all base-classes are old-style, the created class is old-style otherwise it is a new-style class1 since every type subclasses built-in object, we can use object to mark a class as new-style when no true bases exist The statements (a.k.a. the class body) define the set of class attributes which will be shared by all instances of the class 1 We are not considering metaclass now J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 7 / 49
    38. Classes The class statement class classname(base-classes): statement(s) classname is a variable that gets (re)bound to the class object after the class statement finishes executing base-classes is a comma separated series of expressions whose values must be classes if it does not exists, the created class is old-style if all base-classes are old-style, the created class is old-style otherwise it is a new-style class1 since every type subclasses built-in object, we can use object to mark a class as new-style when no true bases exist The statements (a.k.a. the class body) define the set of class attributes which will be shared by all instances of the class 1 We are not considering metaclass now J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 7 / 49
    39. Classes The class statement class classname(base-classes): statement(s) classname is a variable that gets (re)bound to the class object after the class statement finishes executing base-classes is a comma separated series of expressions whose values must be classes if it does not exists, the created class is old-style if all base-classes are old-style, the created class is old-style otherwise it is a new-style class1 since every type subclasses built-in object, we can use object to mark a class as new-style when no true bases exist The statements (a.k.a. the class body) define the set of class attributes which will be shared by all instances of the class 1 We are not considering metaclass now J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 7 / 49
    40. Classes The class statement class classname(base-classes): statement(s) classname is a variable that gets (re)bound to the class object after the class statement finishes executing base-classes is a comma separated series of expressions whose values must be classes if it does not exists, the created class is old-style if all base-classes are old-style, the created class is old-style otherwise it is a new-style class1 since every type subclasses built-in object, we can use object to mark a class as new-style when no true bases exist The statements (a.k.a. the class body) define the set of class attributes which will be shared by all instances of the class 1 We are not considering metaclass now J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 7 / 49
    41. Classes The class statement class classname(base-classes): statement(s) classname is a variable that gets (re)bound to the class object after the class statement finishes executing base-classes is a comma separated series of expressions whose values must be classes if it does not exists, the created class is old-style if all base-classes are old-style, the created class is old-style otherwise it is a new-style class1 since every type subclasses built-in object, we can use object to mark a class as new-style when no true bases exist The statements (a.k.a. the class body) define the set of class attributes which will be shared by all instances of the class 1 We are not considering metaclass now J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 7 / 49
    42. Classes The class statement class classname(base-classes): statement(s) classname is a variable that gets (re)bound to the class object after the class statement finishes executing base-classes is a comma separated series of expressions whose values must be classes if it does not exists, the created class is old-style if all base-classes are old-style, the created class is old-style otherwise it is a new-style class1 since every type subclasses built-in object, we can use object to mark a class as new-style when no true bases exist The statements (a.k.a. the class body) define the set of class attributes which will be shared by all instances of the class 1 We are not considering metaclass now J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 7 / 49
    43. Classes Attributes of class objects Attributes can be bound inside or outside the class body. >>> class C1(object): >>> class C2(object): pass ... x = 23 >>> C2.x = 23 >>> print C1.x >>> print C2.x 23 23 Some attributes are implicitly set: >>> print C1. name , C1. bases C1, (<type ’object’>,) >>> C1. dict [’z’] = 42 >>> print C1.z 42 >>> print C1. dict [’x’] 23 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 8 / 49
    44. Classes Attributes of class objects Attributes can be bound inside or outside the class body. >>> class C1(object): >>> class C2(object): pass ... x = 23 >>> C2.x = 23 >>> print C1.x >>> print C2.x 23 23 Some attributes are implicitly set: >>> print C1. name , C1. bases C1, (<type ’object’>,) >>> C1. dict [’z’] = 42 >>> print C1.z 42 >>> print C1. dict [’x’] 23 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 8 / 49
    45. Classes Attributes of class objects Attributes can be bound inside or outside the class body. >>> class C1(object): >>> class C2(object): pass ... x = 23 >>> C2.x = 23 >>> print C1.x >>> print C2.x 23 23 Some attributes are implicitly set: >>> print C1. name , C1. bases C1, (<type ’object’>,) >>> C1. dict [’z’] = 42 >>> print C1.z 42 >>> print C1. dict [’x’] 23 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 8 / 49
    46. Classes Attributes of class objects Attributes can be bound inside or outside the class body. >>> class C1(object): >>> class C2(object): pass ... x = 23 >>> C2.x = 23 >>> print C1.x >>> print C2.x 23 23 Some attributes are implicitly set: >>> print C1. name , C1. bases C1, (<type ’object’>,) >>> C1. dict [’z’] = 42 >>> print C1.z 42 >>> print C1. dict [’x’] 23 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 8 / 49
    47. Classes Attributes of class objects Attributes can be bound inside or outside the class body. >>> class C1(object): >>> class C2(object): pass ... x = 23 >>> C2.x = 23 >>> print C1.x >>> print C2.x 23 23 Some attributes are implicitly set: >>> print C1. name , C1. bases C1, (<type ’object’>,) >>> C1. dict [’z’] = 42 >>> print C1.z 42 >>> print C1. dict [’x’] 23 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 8 / 49
    48. Classes Attributes of class objects Attributes can be bound inside or outside the class body. >>> class C1(object): >>> class C2(object): pass ... x = 23 >>> C2.x = 23 >>> print C1.x >>> print C2.x 23 23 Some attributes are implicitly set: >>> print C1. name , C1. bases C1, (<type ’object’>,) >>> C1. dict [’z’] = 42 >>> print C1.z 42 >>> print C1. dict [’x’] 23 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 8 / 49
    49. Classes Attributes of class objects Attributes can be bound inside or outside the class body. >>> class C1(object): >>> class C2(object): pass ... x = 23 >>> C2.x = 23 >>> print C1.x >>> print C2.x 23 23 Some attributes are implicitly set: >>> print C1. name , C1. bases C1, (<type ’object’>,) >>> C1. dict [’z’] = 42 >>> print C1.z 42 >>> print C1. dict [’x’] 23 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 8 / 49
    50. Classes Accessing class attributes In statements directly inside the class’ body: >>> class C3(object): ... x = 23 ... y = x + 19 In statements in methods of the class: >>> class C4(object): ... x = 23 ... def amethod(self): ... print C4.x In statements outside the class: >>> class C3(object): ... x = 23 >>> C3.x = 42 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 9 / 49
    51. Classes Accessing class attributes In statements directly inside the class’ body: >>> class C3(object): ... x = 23 ... y = x + 19 In statements in methods of the class: >>> class C4(object): ... x = 23 ... def amethod(self): ... print C4.x In statements outside the class: >>> class C3(object): ... x = 23 >>> C3.x = 42 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 9 / 49
    52. Classes Accessing class attributes In statements directly inside the class’ body: >>> class C3(object): ... x = 23 ... y = x + 19 In statements in methods of the class: >>> class C4(object): ... x = 23 ... def amethod(self): ... print C4.x In statements outside the class: >>> class C3(object): ... x = 23 >>> C3.x = 42 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 9 / 49
    53. Classes Accessing class attributes In statements directly inside the class’ body: >>> class C3(object): ... x = 23 ... y = x + 19 In statements in methods of the class: >>> class C4(object): ... x = 23 ... def amethod(self): ... print C4.x In statements outside the class: >>> class C3(object): ... x = 23 >>> C3.x = 42 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 9 / 49
    54. Classes Accessing class attributes In statements directly inside the class’ body: >>> class C3(object): ... x = 23 ... y = x + 19 In statements in methods of the class: >>> class C4(object): ... x = 23 ... def amethod(self): ... print C4.x In statements outside the class: >>> class C3(object): ... x = 23 >>> C3.x = 42 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 9 / 49
    55. Classes Accessing class attributes In statements directly inside the class’ body: >>> class C3(object): ... x = 23 ... y = x + 19 In statements in methods of the class: >>> class C4(object): ... x = 23 ... def amethod(self): ... print C4.x In statements outside the class: >>> class C3(object): ... x = 23 >>> C3.x = 42 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 9 / 49
    56. Classes Accessing class attributes In statements directly inside the class’ body: >>> class C3(object): ... x = 23 ... y = x + 19 In statements in methods of the class: >>> class C4(object): ... x = 23 ... def amethod(self): ... print C4.x In statements outside the class: >>> class C3(object): ... x = 23 >>> C3.x = 42 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 9 / 49
    57. Classes Accessing class attributes In statements directly inside the class’ body: >>> class C3(object): ... x = 23 ... y = x + 19 In statements in methods of the class: >>> class C4(object): ... x = 23 ... def amethod(self): ... print C4.x In statements outside the class: >>> class C3(object): ... x = 23 >>> C3.x = 42 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 9 / 49
    58. Classes Accessing class attributes In statements directly inside the class’ body: >>> class C3(object): ... x = 23 ... y = x + 19 In statements in methods of the class: >>> class C4(object): ... x = 23 ... def amethod(self): ... print C4.x In statements outside the class: >>> class C3(object): ... x = 23 >>> C3.x = 42 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 9 / 49
    59. Classes Class-private attributes When a statement in the body (or in a method in the body) uses an identifier starting with two underscores (but not ending with them) such as private, the Python compiler changes it to classname private This lets classes to use private names reducing the risk of accidentally duplicating names used elsewhere By convention all identifiers starting with a single underscore are meant to be private in the scope that binds them >>> class C5(object): ... private = 23 >>> print C5.__private AttributeError: class A has no attribute ’ private’ >>> print C5. C5 private 23 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 10 / 49
    60. Classes Class-private attributes When a statement in the body (or in a method in the body) uses an identifier starting with two underscores (but not ending with them) such as private, the Python compiler changes it to classname private This lets classes to use private names reducing the risk of accidentally duplicating names used elsewhere By convention all identifiers starting with a single underscore are meant to be private in the scope that binds them >>> class C5(object): ... private = 23 >>> print C5.__private AttributeError: class A has no attribute ’ private’ >>> print C5. C5 private 23 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 10 / 49
    61. Classes Class-private attributes When a statement in the body (or in a method in the body) uses an identifier starting with two underscores (but not ending with them) such as private, the Python compiler changes it to classname private This lets classes to use private names reducing the risk of accidentally duplicating names used elsewhere By convention all identifiers starting with a single underscore are meant to be private in the scope that binds them >>> class C5(object): ... private = 23 >>> print C5.__private AttributeError: class A has no attribute ’ private’ >>> print C5. C5 private 23 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 10 / 49
    62. Classes Class-private attributes When a statement in the body (or in a method in the body) uses an identifier starting with two underscores (but not ending with them) such as private, the Python compiler changes it to classname private This lets classes to use private names reducing the risk of accidentally duplicating names used elsewhere By convention all identifiers starting with a single underscore are meant to be private in the scope that binds them >>> class C5(object): ... private = 23 >>> print C5.__private AttributeError: class A has no attribute ’ private’ >>> print C5. C5 private 23 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 10 / 49
    63. Classes Function definitions in a class body Most class bodies include def statements since functions (called methods in this context) are important attributes for most class objects A method defined in a class body has a mandatory first parameter (conventionally called self) that refers to the instance on which the method is called (staticmethods and classmethods are not considered now) A class can define a variety of special methods (two leading and two trailing underscores) relating to specific operation on its instances >>> class C5(object): ... \"\"\"This is the docstring of the class. ... It can be accessed by C5. doc \"\"\" ... def hello(self): ... \"And this the docstring of the method\" ... print \"Hello!!\" J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 11 / 49
    64. Classes Function definitions in a class body Most class bodies include def statements since functions (called methods in this context) are important attributes for most class objects A method defined in a class body has a mandatory first parameter (conventionally called self) that refers to the instance on which the method is called (staticmethods and classmethods are not considered now) A class can define a variety of special methods (two leading and two trailing underscores) relating to specific operation on its instances >>> class C5(object): ... \"\"\"This is the docstring of the class. ... It can be accessed by C5. doc \"\"\" ... def hello(self): ... \"And this the docstring of the method\" ... print \"Hello!!\" J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 11 / 49
    65. Classes Function definitions in a class body Most class bodies include def statements since functions (called methods in this context) are important attributes for most class objects A method defined in a class body has a mandatory first parameter (conventionally called self) that refers to the instance on which the method is called (staticmethods and classmethods are not considered now) A class can define a variety of special methods (two leading and two trailing underscores) relating to specific operation on its instances >>> class C5(object): ... \"\"\"This is the docstring of the class. ... It can be accessed by C5. doc \"\"\" ... def hello(self): ... \"And this the docstring of the method\" ... print \"Hello!!\" J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 11 / 49
    66. Classes Function definitions in a class body Most class bodies include def statements since functions (called methods in this context) are important attributes for most class objects A method defined in a class body has a mandatory first parameter (conventionally called self) that refers to the instance on which the method is called (staticmethods and classmethods are not considered now) A class can define a variety of special methods (two leading and two trailing underscores) relating to specific operation on its instances >>> class C5(object): ... \"\"\"This is the docstring of the class. ... It can be accessed by C5. doc \"\"\" ... def hello(self): ... \"And this the docstring of the method\" ... print \"Hello!!\" J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 11 / 49
    67. Instances I Creating Instances 1 To create an instance of a >>> anInstance = C5() class, call the class object as >>> isinstance(anInstance, C5) if it were a function True >>> class C6(object): If it defines or inherits ... def init (self, n): init , calling the class ... self.x = n object implicitly calls it to >>> anInstance = C6(42) perform any needed >>> print anInstance.x instance-specific 42 initialisation >>> anInstance.z = 8 You can give an instance an >>> print anInstance.z attribute by binding a value 8 to an attribute reference J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 12 / 49
    68. Instances I Creating Instances 1 To create an instance of a >>> anInstance = C5() class, call the class object as >>> isinstance(anInstance, C5) if it were a function True >>> class C6(object): If it defines or inherits ... def init (self, n): init , calling the class ... self.x = n object implicitly calls it to >>> anInstance = C6(42) perform any needed >>> print anInstance.x instance-specific 42 initialisation >>> anInstance.z = 8 You can give an instance an >>> print anInstance.z attribute by binding a value 8 to an attribute reference J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 12 / 49
    69. Instances I Creating Instances 1 To create an instance of a >>> anInstance = C5() class, call the class object as >>> isinstance(anInstance, C5) if it were a function True >>> class C6(object): If it defines or inherits ... def init (self, n): init , calling the class ... self.x = n object implicitly calls it to >>> anInstance = C6(42) perform any needed >>> print anInstance.x instance-specific 42 initialisation >>> anInstance.z = 8 You can give an instance an >>> print anInstance.z attribute by binding a value 8 to an attribute reference J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 12 / 49
    70. Instances I Creating Instances 1 To create an instance of a >>> anInstance = C5() class, call the class object as >>> isinstance(anInstance, C5) if it were a function True >>> class C6(object): If it defines or inherits ... def init (self, n): init , calling the class ... self.x = n object implicitly calls it to >>> anInstance = C6(42) perform any needed >>> print anInstance.x instance-specific 42 initialisation >>> anInstance.z = 8 You can give an instance an >>> print anInstance.z attribute by binding a value 8 to an attribute reference J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 12 / 49
    71. Instances I Creating Instances 1 To create an instance of a >>> anInstance = C5() class, call the class object as >>> isinstance(anInstance, C5) if it were a function True >>> class C6(object): If it defines or inherits ... def init (self, n): init , calling the class ... self.x = n object implicitly calls it to >>> anInstance = C6(42) perform any needed >>> print anInstance.x instance-specific 42 initialisation >>> anInstance.z = 8 You can give an instance an >>> print anInstance.z attribute by binding a value 8 to an attribute reference J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 12 / 49
    72. Instances I Creating Instances 1 To create an instance of a >>> anInstance = C5() class, call the class object as >>> isinstance(anInstance, C5) if it were a function True >>> class C6(object): If it defines or inherits ... def init (self, n): init , calling the class ... self.x = n object implicitly calls it to >>> anInstance = C6(42) perform any needed >>> print anInstance.x instance-specific 42 initialisation >>> anInstance.z = 8 You can give an instance an >>> print anInstance.z attribute by binding a value 8 to an attribute reference J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 12 / 49
    73. Instances I Creating Instances 1 To create an instance of a >>> anInstance = C5() class, call the class object as >>> isinstance(anInstance, C5) if it were a function True >>> class C6(object): If it defines or inherits ... def init (self, n): init , calling the class ... self.x = n object implicitly calls it to >>> anInstance = C6(42) perform any needed >>> print anInstance.x instance-specific 42 initialisation >>> anInstance.z = 8 You can give an instance an >>> print anInstance.z attribute by binding a value 8 to an attribute reference J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 12 / 49
    74. Instances I Creating Instances 1 To create an instance of a >>> anInstance = C5() class, call the class object as >>> isinstance(anInstance, C5) if it were a function True >>> class C6(object): If it defines or inherits ... def init (self, n): init , calling the class ... self.x = n object implicitly calls it to >>> anInstance = C6(42) perform any needed >>> print anInstance.x instance-specific 42 initialisation >>> anInstance.z = 8 You can give an instance an >>> print anInstance.z attribute by binding a value 8 to an attribute reference J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 12 / 49
    75. Instances I Creating Instances 1 To create an instance of a >>> anInstance = C5() class, call the class object as >>> isinstance(anInstance, C5) if it were a function True >>> class C6(object): If it defines or inherits ... def init (self, n): init , calling the class ... self.x = n object implicitly calls it to >>> anInstance = C6(42) perform any needed >>> print anInstance.x instance-specific 42 initialisation >>> anInstance.z = 8 You can give an instance an >>> print anInstance.z attribute by binding a value 8 to an attribute reference J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 12 / 49
    76. Instances I Creating Instances 1 To create an instance of a >>> anInstance = C5() class, call the class object as >>> isinstance(anInstance, C5) if it were a function True >>> class C6(object): If it defines or inherits ... def init (self, n): init , calling the class ... self.x = n object implicitly calls it to >>> anInstance = C6(42) perform any needed >>> print anInstance.x instance-specific 42 initialisation >>> anInstance.z = 8 You can give an instance an >>> print anInstance.z attribute by binding a value 8 to an attribute reference J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 12 / 49
    77. Instances I Creating Instances 1 To create an instance of a >>> anInstance = C5() class, call the class object as >>> isinstance(anInstance, C5) if it were a function True >>> class C6(object): If it defines or inherits ... def init (self, n): init , calling the class ... self.x = n object implicitly calls it to >>> anInstance = C6(42) perform any needed >>> print anInstance.x instance-specific 42 initialisation >>> anInstance.z = 8 You can give an instance an >>> print anInstance.z attribute by binding a value 8 to an attribute reference J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 12 / 49
    78. Instances I Creating Instances 1 To create an instance of a >>> anInstance = C5() class, call the class object as >>> isinstance(anInstance, C5) if it were a function True >>> class C6(object): If it defines or inherits ... def init (self, n): init , calling the class ... self.x = n object implicitly calls it to >>> anInstance = C6(42) perform any needed >>> print anInstance.x instance-specific 42 initialisation >>> anInstance.z = 8 You can give an instance an >>> print anInstance.z attribute by binding a value 8 to an attribute reference J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 12 / 49
    79. Instances I Creating Instances 1 To create an instance of a >>> anInstance = C5() class, call the class object as >>> isinstance(anInstance, C5) if it were a function True >>> class C6(object): If it defines or inherits ... def init (self, n): init , calling the class ... self.x = n object implicitly calls it to >>> anInstance = C6(42) perform any needed >>> print anInstance.x instance-specific 42 initialisation >>> anInstance.z = 8 You can give an instance an >>> print anInstance.z attribute by binding a value 8 to an attribute reference J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 12 / 49
    80. Instances I Attributes of Instance Objects Attributes can be bound inside or outside class methods >>> class C1(object): >>> class C2(object): ... def amethod(self, n=8): ... pass ... self.n = n >>> d = C2() >>> c = C1() >>> d.n = 15 >>> c.amethod() >>> print d.n >>> print c.n 15 8 Some attributes are implicitly set (both can be rebound but not unbound): >>> print d. class <class ’ main .C2’> >>> d. dict [’z’] = 42 >>> print d.z 42 >>> print d. dict [’n’] 15 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 13 / 49
    81. Instances I Attributes of Instance Objects Attributes can be bound inside or outside class methods >>> class C1(object): >>> class C2(object): ... def amethod(self, n=8): ... pass ... self.n = n >>> d = C2() >>> c = C1() >>> d.n = 15 >>> c.amethod() >>> print d.n >>> print c.n 15 8 Some attributes are implicitly set (both can be rebound but not unbound): >>> print d. class <class ’ main .C2’> >>> d. dict [’z’] = 42 >>> print d.z 42 >>> print d. dict [’n’] 15 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 13 / 49
    82. Instances I Attributes of Instance Objects Attributes can be bound inside or outside class methods >>> class C1(object): >>> class C2(object): ... def amethod(self, n=8): ... pass ... self.n = n >>> d = C2() >>> c = C1() >>> d.n = 15 >>> c.amethod() >>> print d.n >>> print c.n 15 8 Some attributes are implicitly set (both can be rebound but not unbound): >>> print d. class <class ’ main .C2’> >>> d. dict [’z’] = 42 >>> print d.z 42 >>> print d. dict [’n’] 15 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 13 / 49
    83. Instances I Attributes of Instance Objects Attributes can be bound inside or outside class methods >>> class C1(object): >>> class C2(object): ... def amethod(self, n=8): ... pass ... self.n = n >>> d = C2() >>> c = C1() >>> d.n = 15 >>> c.amethod() >>> print d.n >>> print c.n 15 8 Some attributes are implicitly set (both can be rebound but not unbound): >>> print d. class <class ’ main .C2’> >>> d. dict [’z’] = 42 >>> print d.z 42 >>> print d. dict [’n’] 15 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 13 / 49
    84. Instances I Attributes of Instance Objects Attributes can be bound inside or outside class methods >>> class C1(object): >>> class C2(object): ... def amethod(self, n=8): ... pass ... self.n = n >>> d = C2() >>> c = C1() >>> d.n = 15 >>> c.amethod() >>> print d.n >>> print c.n 15 8 Some attributes are implicitly set (both can be rebound but not unbound): >>> print d. class <class ’ main .C2’> >>> d. dict [’z’] = 42 >>> print d.z 42 >>> print d. dict [’n’] 15 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 13 / 49
    85. Instances I Attributes of Instance Objects Attributes can be bound inside or outside class methods >>> class C1(object): >>> class C2(object): ... def amethod(self, n=8): ... pass ... self.n = n >>> d = C2() >>> c = C1() >>> d.n = 15 >>> c.amethod() >>> print d.n >>> print c.n 15 8 Some attributes are implicitly set (both can be rebound but not unbound): >>> print d. class <class ’ main .C2’> >>> d. dict [’z’] = 42 >>> print d.z 42 >>> print d. dict [’n’] 15 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 13 / 49
    86. Instances I Attributes of Instance Objects Attributes can be bound inside or outside class methods >>> class C1(object): >>> class C2(object): ... def amethod(self, n=8): ... pass ... self.n = n >>> d = C2() >>> c = C1() >>> d.n = 15 >>> c.amethod() >>> print d.n >>> print c.n 15 8 Some attributes are implicitly set (both can be rebound but not unbound): >>> print d. class <class ’ main .C2’> >>> d. dict [’z’] = 42 >>> print d.z 42 >>> print d. dict [’n’] 15 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 13 / 49
    87. Descriptors Descriptors A descriptor is any new-style object whose class supplies a special method named get Descriptors that are class attributes control the semantics of accessing and setting attributes on instances of that class If a descriptor’s class also supplies method set then it is called an overriding descriptor (a.k.a. data descriptor) If not, it is called non-overriding (a.k.a. non-data) descriptor Function objects (and methods) are non-overriding descriptors Descriptors are the mechanism behind properties, methods, static methods, class methods, and super (cooperative super-classes) The descriptor protocol also contains method delete for unbinding attributes but it is seldom used J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 14 / 49
    88. Descriptors Descriptors A descriptor is any new-style object whose class supplies a special method named get Descriptors that are class attributes control the semantics of accessing and setting attributes on instances of that class If a descriptor’s class also supplies method set then it is called an overriding descriptor (a.k.a. data descriptor) If not, it is called non-overriding (a.k.a. non-data) descriptor Function objects (and methods) are non-overriding descriptors Descriptors are the mechanism behind properties, methods, static methods, class methods, and super (cooperative super-classes) The descriptor protocol also contains method delete for unbinding attributes but it is seldom used J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 14 / 49
    89. Descriptors Descriptors A descriptor is any new-style object whose class supplies a special method named get Descriptors that are class attributes control the semantics of accessing and setting attributes on instances of that class If a descriptor’s class also supplies method set then it is called an overriding descriptor (a.k.a. data descriptor) If not, it is called non-overriding (a.k.a. non-data) descriptor Function objects (and methods) are non-overriding descriptors Descriptors are the mechanism behind properties, methods, static methods, class methods, and super (cooperative super-classes) The descriptor protocol also contains method delete for unbinding attributes but it is seldom used J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 14 / 49
    90. Descriptors Descriptors A descriptor is any new-style object whose class supplies a special method named get Descriptors that are class attributes control the semantics of accessing and setting attributes on instances of that class If a descriptor’s class also supplies method set then it is called an overriding descriptor (a.k.a. data descriptor) If not, it is called non-overriding (a.k.a. non-data) descriptor Function objects (and methods) are non-overriding descriptors Descriptors are the mechanism behind properties, methods, static methods, class methods, and super (cooperative super-classes) The descriptor protocol also contains method delete for unbinding attributes but it is seldom used J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 14 / 49
    91. Descriptors Descriptors A descriptor is any new-style object whose class supplies a special method named get Descriptors that are class attributes control the semantics of accessing and setting attributes on instances of that class If a descriptor’s class also supplies method set then it is called an overriding descriptor (a.k.a. data descriptor) If not, it is called non-overriding (a.k.a. non-data) descriptor Function objects (and methods) are non-overriding descriptors Descriptors are the mechanism behind properties, methods, static methods, class methods, and super (cooperative super-classes) The descriptor protocol also contains method delete for unbinding attributes but it is seldom used J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 14 / 49
    92. Descriptors Descriptors A descriptor is any new-style object whose class supplies a special method named get Descriptors that are class attributes control the semantics of accessing and setting attributes on instances of that class If a descriptor’s class also supplies method set then it is called an overriding descriptor (a.k.a. data descriptor) If not, it is called non-overriding (a.k.a. non-data) descriptor Function objects (and methods) are non-overriding descriptors Descriptors are the mechanism behind properties, methods, static methods, class methods, and super (cooperative super-classes) The descriptor protocol also contains method delete for unbinding attributes but it is seldom used J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 14 / 49
    93. Descriptors Descriptors A descriptor is any new-style object whose class supplies a special method named get Descriptors that are class attributes control the semantics of accessing and setting attributes on instances of that class If a descriptor’s class also supplies method set then it is called an overriding descriptor (a.k.a. data descriptor) If not, it is called non-overriding (a.k.a. non-data) descriptor Function objects (and methods) are non-overriding descriptors Descriptors are the mechanism behind properties, methods, static methods, class methods, and super (cooperative super-classes) The descriptor protocol also contains method delete for unbinding attributes but it is seldom used J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 14 / 49
    94. Descriptors A Descriptor Example >>> class Area(object): ... \"\"\"An overriding descriptor\"\"\" ... def get (self, obj, klass): ... return obj.x * obj.y ... def set (self, obj, value): ... raise AttributeError >>> class Rectangle(object): ... \"\"\"A new-style class for representing rectangles\"\"\" ... area = Area() ... def init (self, x, y): ... self.x = x ... self.y = y >>> r = Rectangle(5, 10) >>> print r.area 50 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 15 / 49
    95. Descriptors Referencing Attributes Attribute Reference Basics An attribute reference is an expression of the form x.name, where x is an expression and name is an identifier Many kinds of Python objects have attributes, but an attribute reference when x refers to a class or an instance has special rich semantics The mechanics of attribute getting is defined in the special method getattribute The predefined behaviour is defined in the implementation of this method in the type (for class attributes) and object (for instance attributes) built-in types J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 16 / 49
    96. Descriptors Referencing Attributes Attribute Reference Basics An attribute reference is an expression of the form x.name, where x is an expression and name is an identifier Many kinds of Python objects have attributes, but an attribute reference when x refers to a class or an instance has special rich semantics The mechanics of attribute getting is defined in the special method getattribute The predefined behaviour is defined in the implementation of this method in the type (for class attributes) and object (for instance attributes) built-in types J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 16 / 49
    97. Descriptors Referencing Attributes Attribute Reference Basics An attribute reference is an expression of the form x.name, where x is an expression and name is an identifier Many kinds of Python objects have attributes, but an attribute reference when x refers to a class or an instance has special rich semantics The mechanics of attribute getting is defined in the special method getattribute The predefined behaviour is defined in the implementation of this method in the type (for class attributes) and object (for instance attributes) built-in types J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 16 / 49
    98. Descriptors Referencing Attributes Attribute Reference Basics An attribute reference is an expression of the form x.name, where x is an expression and name is an identifier Many kinds of Python objects have attributes, but an attribute reference when x refers to a class or an instance has special rich semantics The mechanics of attribute getting is defined in the special method getattribute The predefined behaviour is defined in the implementation of this method in the type (for class attributes) and object (for instance attributes) built-in types J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 16 / 49
    99. Descriptors Referencing Attributes Getting an attribute from a class When you use the syntax C.name to refer to an attribute on a class object C, the look-up proceeds in two steps: 1 When ’name’ is a key in C. dict , C.name fetches the value v from C. dict [’name’]. If v is a descriptor (i.e. type(v) supplies a get method), then type(v). get (v,None,C) is returned Otherwise, ir returns v 2 Otherwise, it delegates the look-up to its base classes (in method resolution order) When these look-ups steps do not find an attribute, Python raises an AttributeError exception. J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 17 / 49
    100. Descriptors Referencing Attributes Getting an attribute from a class When you use the syntax C.name to refer to an attribute on a class object C, the look-up proceeds in two steps: 1 When ’name’ is a key in C. dict , C.name fetches the value v from C. dict [’name’]. If v is a descriptor (i.e. type(v) supplies a get method), then type(v). get (v,None,C) is returned Otherwise, ir returns v 2 Otherwise, it delegates the look-up to its base classes (in method resolution order) When these look-ups steps do not find an attribute, Python raises an AttributeError exception. J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 17 / 49
    101. Descriptors Referencing Attributes Getting an attribute from a class When you use the syntax C.name to refer to an attribute on a class object C, the look-up proceeds in two steps: 1 When ’name’ is a key in C. dict , C.name fetches the value v from C. dict [’name’]. If v is a descriptor (i.e. type(v) supplies a get method), then type(v). get (v,None,C) is returned Otherwise, ir returns v 2 Otherwise, it delegates the look-up to its base classes (in method resolution order) When these look-ups steps do not find an attribute, Python raises an AttributeError exception. J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 17 / 49
    102. Descriptors Referencing Attributes Getting an attribute from a class When you use the syntax C.name to refer to an attribute on a class object C, the look-up proceeds in two steps: 1 When ’name’ is a key in C. dict , C.name fetches the value v from C. dict [’name’]. If v is a descriptor (i.e. type(v) supplies a get method), then type(v). get (v,None,C) is returned Otherwise, ir returns v 2 Otherwise, it delegates the look-up to its base classes (in method resolution order) When these look-ups steps do not find an attribute, Python raises an AttributeError exception. J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 17 / 49
    103. Descriptors Referencing Attributes Getting an attribute from a class When you use the syntax C.name to refer to an attribute on a class object C, the look-up proceeds in two steps: 1 When ’name’ is a key in C. dict , C.name fetches the value v from C. dict [’name’]. If v is a descriptor (i.e. type(v) supplies a get method), then type(v). get (v,None,C) is returned Otherwise, ir returns v 2 Otherwise, it delegates the look-up to its base classes (in method resolution order) When these look-ups steps do not find an attribute, Python raises an AttributeError exception. J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 17 / 49
    104. Descriptors Referencing Attributes Getting an attribute from a class When you use the syntax C.name to refer to an attribute on a class object C, the look-up proceeds in two steps: 1 When ’name’ is a key in C. dict , C.name fetches the value v from C. dict [’name’]. If v is a descriptor (i.e. type(v) supplies a get method), then type(v). get (v,None,C) is returned Otherwise, ir returns v 2 Otherwise, it delegates the look-up to its base classes (in method resolution order) When these look-ups steps do not find an attribute, Python raises an AttributeError exception. J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 17 / 49
    105. Descriptors Referencing Attributes Getting an attribute from a class When you use the syntax C.name to refer to an attribute on a class object C, the look-up proceeds in two steps: 1 When ’name’ is a key in C. dict , C.name fetches the value v from C. dict [’name’]. If v is a descriptor (i.e. type(v) supplies a get method), then type(v). get (v,None,C) is returned Otherwise, ir returns v 2 Otherwise, it delegates the look-up to its base classes (in method resolution order) When these look-ups steps do not find an attribute, Python raises an AttributeError exception. J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 17 / 49
    106. Descriptors Referencing Attributes Getting an attribute from an instance I When you use the syntax x.name to refer to an attribute of instance x of class C, the look-up proceeds in three steps: 1 When ’name’ is found in C (or in one of C’s ancestor classes) as the name of an overriding descriptor v (i.e. type(v) supplies both get and set ), then the value of x.name is type(v). get (v,x,C) 2 Otherwise, when ’name’ is key in x. dict , x.name fetches and returns x. dict [’name’] 3 Otherwise, x.name delegates the look-up to x’s class (looking into C. dict or delegating to C’s bases) and if a descriptor v is found, the overall result is again type(v). get (v,x,C). if a nondescriptor value v is found, the result is v. J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 18 / 49
    107. Descriptors Referencing Attributes Getting an attribute from an instance I When you use the syntax x.name to refer to an attribute of instance x of class C, the look-up proceeds in three steps: 1 When ’name’ is found in C (or in one of C’s ancestor classes) as the name of an overriding descriptor v (i.e. type(v) supplies both get and set ), then the value of x.name is type(v). get (v,x,C) 2 Otherwise, when ’name’ is key in x. dict , x.name fetches and returns x. dict [’name’] 3 Otherwise, x.name delegates the look-up to x’s class (looking into C. dict or delegating to C’s bases) and if a descriptor v is found, the overall result is again type(v). get (v,x,C). if a nondescriptor value v is found, the result is v. J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 18 / 49
    108. Descriptors Referencing Attributes Getting an attribute from an instance I When you use the syntax x.name to refer to an attribute of instance x of class C, the look-up proceeds in three steps: 1 When ’name’ is found in C (or in one of C’s ancestor classes) as the name of an overriding descriptor v (i.e. type(v) supplies both get and set ), then the value of x.name is type(v). get (v,x,C) 2 Otherwise, when ’name’ is key in x. dict , x.name fetches and returns x. dict [’name’] 3 Otherwise, x.name delegates the look-up to x’s class (looking into C. dict or delegating to C’s bases) and if a descriptor v is found, the overall result is again type(v). get (v,x,C). if a nondescriptor value v is found, the result is v. J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 18 / 49
    109. Descriptors Referencing Attributes Getting an attribute from an instance I When you use the syntax x.name to refer to an attribute of instance x of class C, the look-up proceeds in three steps: 1 When ’name’ is found in C (or in one of C’s ancestor classes) as the name of an overriding descriptor v (i.e. type(v) supplies both get and set ), then the value of x.name is type(v). get (v,x,C) 2 Otherwise, when ’name’ is key in x. dict , x.name fetches and returns x. dict [’name’] 3 Otherwise, x.name delegates the look-up to x’s class (looking into C. dict or delegating to C’s bases) and if a descriptor v is found, the overall result is again type(v). get (v,x,C). if a nondescriptor value v is found, the result is v. J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 18 / 49
    110. Descriptors Referencing Attributes Getting an attribute from an instance I When you use the syntax x.name to refer to an attribute of instance x of class C, the look-up proceeds in three steps: 1 When ’name’ is found in C (or in one of C’s ancestor classes) as the name of an overriding descriptor v (i.e. type(v) supplies both get and set ), then the value of x.name is type(v). get (v,x,C) 2 Otherwise, when ’name’ is key in x. dict , x.name fetches and returns x. dict [’name’] 3 Otherwise, x.name delegates the look-up to x’s class (looking into C. dict or delegating to C’s bases) and if a descriptor v is found, the overall result is again type(v). get (v,x,C). if a nondescriptor value v is found, the result is v. J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 18 / 49
    111. Descriptors Referencing Attributes Getting an attribute from an instance I When you use the syntax x.name to refer to an attribute of instance x of class C, the look-up proceeds in three steps: 1 When ’name’ is found in C (or in one of C’s ancestor classes) as the name of an overriding descriptor v (i.e. type(v) supplies both get and set ), then the value of x.name is type(v). get (v,x,C) 2 Otherwise, when ’name’ is key in x. dict , x.name fetches and returns x. dict [’name’] 3 Otherwise, x.name delegates the look-up to x’s class (looking into C. dict or delegating to C’s bases) and if a descriptor v is found, the overall result is again type(v). get (v,x,C). if a nondescriptor value v is found, the result is v. J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 18 / 49
    112. Descriptors Referencing Attributes Getting an attribute from an instance II When these look-ups steps do not find an attribute, Python either: raises an AttributeError exception, or if C defines or inherits special method getattr , calls C. getattr (x, ’name’) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 19 / 49
    113. Descriptors Referencing Attributes Getting an attribute from an instance II When these look-ups steps do not find an attribute, Python either: raises an AttributeError exception, or if C defines or inherits special method getattr , calls C. getattr (x, ’name’) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 19 / 49
    114. Descriptors Referencing Attributes Getting an attribute from an instance II When these look-ups steps do not find an attribute, Python either: raises an AttributeError exception, or if C defines or inherits special method getattr , calls C. getattr (x, ’name’) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 19 / 49
    115. Descriptors Referencing Attributes Setting an attribute The attribute look-up steps happens when referring to an attribute, not when binding an attribute (e.g. with x.name=v) When binding an attribute whose name is not special, only the dict entry for the attribute is affected Unless a setattr method is defined (or inherited) in x’s class Or name corresponds to an overriding descriptor in x’s class (or one of its ancestors) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 20 / 49
    116. Descriptors Referencing Attributes Setting an attribute The attribute look-up steps happens when referring to an attribute, not when binding an attribute (e.g. with x.name=v) When binding an attribute whose name is not special, only the dict entry for the attribute is affected Unless a setattr method is defined (or inherited) in x’s class Or name corresponds to an overriding descriptor in x’s class (or one of its ancestors) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 20 / 49
    117. Descriptors Referencing Attributes Setting an attribute The attribute look-up steps happens when referring to an attribute, not when binding an attribute (e.g. with x.name=v) When binding an attribute whose name is not special, only the dict entry for the attribute is affected Unless a setattr method is defined (or inherited) in x’s class Or name corresponds to an overriding descriptor in x’s class (or one of its ancestors) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 20 / 49
    118. Descriptors Referencing Attributes Setting an attribute The attribute look-up steps happens when referring to an attribute, not when binding an attribute (e.g. with x.name=v) When binding an attribute whose name is not special, only the dict entry for the attribute is affected Unless a setattr method is defined (or inherited) in x’s class Or name corresponds to an overriding descriptor in x’s class (or one of its ancestors) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 20 / 49
    119. Descriptors Bound and Unbound Methods Functions are descriptors The get method of a function either returns >>> class C(object): an unbound ... def init (self, x): self.x = x method object, or >>> def fun(obj): return obj.x a bound method >>> fun object <function fun at 0xb7d89c6c> that wraps the >>> C.met = fun function. >>> o = C(8) The key difference is >>> o that a unbound < main .C object at 0xb7d9046c> method is not >>> C.met associated with a <unbound method C.fun> particular instance >>> o.met while a bound is <bound method C.fun of Other callables (such < main .C object at 0xb7d9046c>> as built-ins) are not descriptors J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 21 / 49
    120. Descriptors Bound and Unbound Methods Unbound methods C.met is fun. get (None, C) It has also three attributes: im class, im self, im func You can call it as its im func, but the first argument must be an instance of im class (or descendant) >>> C.met == fun. get (None, C) True >>> C.met.im class is C True >>> C.met.im self is None True >>> C.met.im func is fun True >>> class D(object): pass >>> C.met(D()) Traceback (most recent call last): File \" <stdin> \", line 1, in ? TypeError: unbound method fun() must be called with C instance as first argument (got D instance instead) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 22 / 49
    121. Descriptors Bound and Unbound Methods Unbound methods C.met is fun. get (None, C) It has also three attributes: im class, im self, im func You can call it as its im func, but the first argument must be an instance of im class (or descendant) >>> C.met == fun. get (None, C) True >>> C.met.im class is C True >>> C.met.im self is None True >>> C.met.im func is fun True >>> class D(object): pass >>> C.met(D()) Traceback (most recent call last): File \" <stdin> \", line 1, in ? TypeError: unbound method fun() must be called with C instance as first argument (got D instance instead) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 22 / 49
    122. Descriptors Bound and Unbound Methods Unbound methods C.met is fun. get (None, C) It has also three attributes: im class, im self, im func You can call it as its im func, but the first argument must be an instance of im class (or descendant) >>> C.met == fun. get (None, C) True >>> C.met.im class is C True >>> C.met.im self is None True >>> C.met.im func is fun True >>> class D(object): pass >>> C.met(D()) Traceback (most recent call last): File \" <stdin> \", line 1, in ? TypeError: unbound method fun() must be called with C instance as first argument (got D instance instead) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 22 / 49
    123. Descriptors Bound and Unbound Methods Unbound methods C.met is fun. get (None, C) It has also three attributes: im class, im self, im func You can call it as its im func, but the first argument must be an instance of im class (or descendant) >>> C.met == fun. get (None, C) True >>> C.met.im class is C True >>> C.met.im self is None True >>> C.met.im func is fun True >>> class D(object): pass >>> C.met(D()) Traceback (most recent call last): File \" <stdin> \", line 1, in ? TypeError: unbound method fun() must be called with C instance as first argument (got D instance instead) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 22 / 49
    124. Descriptors Bound and Unbound Methods Unbound methods C.met is fun. get (None, C) It has also three attributes: im class, im self, im func You can call it as its im func, but the first argument must be an instance of im class (or descendant) >>> C.met == fun. get (None, C) True >>> C.met.im class is C True >>> C.met.im self is None True >>> C.met.im func is fun True >>> class D(object): pass >>> C.met(D()) Traceback (most recent call last): File \" <stdin> \", line 1, in ? TypeError: unbound method fun() must be called with C instance as first argument (got D instance instead) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 22 / 49
    125. Descriptors Bound and Unbound Methods Unbound methods C.met is fun. get (None, C) It has also three attributes: im class, im self, im func You can call it as its im func, but the first argument must be an instance of im class (or descendant) >>> C.met == fun. get (None, C) True >>> C.met.im class is C True >>> C.met.im self is None True >>> C.met.im func is fun True >>> class D(object): pass >>> C.met(D()) Traceback (most recent call last): File \" <stdin> \", line 1, in ? TypeError: unbound method fun() must be called with C instance as first argument (got D instance instead) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 22 / 49
    126. Descriptors Bound and Unbound Methods Bound methods o.met is fun. get (o, type(o)) It has three attributes: im class, im self, im func When called, it calls im func passing im self as first argument >>> o.met == fun. get (o, type(o)) True >>> o.met.im class is C True >>> o.met.im self is o True >>> o.met.im func is fun True >>> o.met.im func(o.met.im self) 8 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 23 / 49
    127. Descriptors Bound and Unbound Methods Bound methods o.met is fun. get (o, type(o)) It has three attributes: im class, im self, im func When called, it calls im func passing im self as first argument >>> o.met == fun. get (o, type(o)) True >>> o.met.im class is C True >>> o.met.im self is o True >>> o.met.im func is fun True >>> o.met.im func(o.met.im self) 8 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 23 / 49
    128. Descriptors Bound and Unbound Methods Bound methods o.met is fun. get (o, type(o)) It has three attributes: im class, im self, im func When called, it calls im func passing im self as first argument >>> o.met == fun. get (o, type(o)) True >>> o.met.im class is C True >>> o.met.im self is o True >>> o.met.im func is fun True >>> o.met.im func(o.met.im self) 8 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 23 / 49
    129. Descriptors Bound and Unbound Methods Bound methods o.met is fun. get (o, type(o)) It has three attributes: im class, im self, im func When called, it calls im func passing im self as first argument >>> o.met == fun. get (o, type(o)) True >>> o.met.im class is C True >>> o.met.im self is o True >>> o.met.im func is fun True >>> o.met.im func(o.met.im self) 8 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 23 / 49
    130. Descriptors Bound and Unbound Methods Bound methods o.met is fun. get (o, type(o)) It has three attributes: im class, im self, im func When called, it calls im func passing im self as first argument >>> o.met == fun. get (o, type(o)) True >>> o.met.im class is C True >>> o.met.im self is o True >>> o.met.im func is fun True >>> o.met.im func(o.met.im self) 8 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 23 / 49
    131. Descriptors Bound and Unbound Methods Bound methods o.met is fun. get (o, type(o)) It has three attributes: im class, im self, im func When called, it calls im func passing im self as first argument >>> o.met == fun. get (o, type(o)) True >>> o.met.im class is C True >>> o.met.im self is o True >>> o.met.im func is fun True >>> o.met.im func(o.met.im self) 8 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 23 / 49
    132. Descriptors Bound and Unbound Methods Simulation of the built-in function type class Function(object): \"\"\"Simulation of the built-in function type\"\"\" def __init__(self, fun): self.fun = fun def __call__(self, *args, **kwargs): return self.fun(*args, **kwargs) def __get__(self, obj, cls): return InstanceMethod(self.fun, obj, cls) def __repr__(self): return \"Function-wrapper of %s\" % (self.fun,) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 24 / 49
    133. Descriptors Bound and Unbound Methods Simulation of the built-in instancemethod type class InstanceMethod(object): def __init__(self, fun, obj, cls): self.im_func = fun self.im_self = obj self.im_class = cls def __call__(self, *args, **kwargs): if self.im_self is None: # Unbound method call if not isinstance(args[0], self.im_class): raise TypeError, \"%s should be called with an instance of %s\" % \\ (self, self.im_class.__name__) else: return self.im_func(*args, **kwargs) else: # Bound method call return self.im_func(self.im_self, *args, **kwargs) def __repr__(self): if self.im_self is None: return \"UnboundMethod %s.%s\" % \\ (self.im_class.__name__, self.im_func.__name__) else: return \"BoundMethod %s.%s of %s\" % \\ (self.im_class.__name__, self.im_func.__name__, self.im_self) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 25 / 49
    134. Descriptors Bound and Unbound Methods Closures, Bound-methods and callable objects def make_adder_as_closure(augend): def add(addend): return addend + augend return add def make_adder_as_bound_method(augend): class Adder(object): def init (self, augend): self.augend = augend def add(self, addend): return addend + self.augend return Adder(augend).add def make_adder_as_callable(augend): class Adder(object): def init (self, augend): self.augend = augend def call (self, addend): return addend + self.augend return Adder(augend) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 26 / 49
    135. Descriptors Bound and Unbound Methods Closures, Bound-methods and callable objects def make_adder_as_closure(augend): def add(addend): return addend + augend return add def make_adder_as_bound_method(augend): class Adder(object): def init (self, augend): self.augend = augend def add(self, addend): return addend + self.augend return Adder(augend).add def make_adder_as_callable(augend): class Adder(object): def init (self, augend): self.augend = augend def call (self, addend): return addend + self.augend return Adder(augend) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 26 / 49
    136. Descriptors Bound and Unbound Methods Closures, Bound-methods and callable objects def make_adder_as_closure(augend): def add(addend): return addend + augend return add def make_adder_as_bound_method(augend): class Adder(object): def init (self, augend): self.augend = augend def add(self, addend): return addend + self.augend return Adder(augend).add def make_adder_as_callable(augend): class Adder(object): def init (self, augend): self.augend = augend def call (self, addend): return addend + self.augend return Adder(augend) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 26 / 49
    137. Descriptors Bound and Unbound Methods Closures, Bound-methods and callable objects def make_adder_as_closure(augend): def add(addend): return addend + augend return add def make_adder_as_bound_method(augend): class Adder(object): def init (self, augend): self.augend = augend def add(self, addend): return addend + self.augend return Adder(augend).add def make_adder_as_callable(augend): class Adder(object): def init (self, augend): self.augend = augend def call (self, addend): return addend + self.augend return Adder(augend) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 26 / 49
    138. Descriptors Properties Defining properties The built-in property(fget=None, fset=None, fdel=None, doc=None) simplifies the creation of descriptors for calculated attributes Remember that descriptors only work their magic if defined as class attributes >>> class Rectangle(object): ... \"\"\"A new-style class for representing rectangles\"\"\" ... def __init__(self, x, y): ... self.x = x ... self.y = y ... def getArea(self): ... return self.x * self.y ... area = property(fget=getArea, doc=\"Area of the rectangle\") ... del getArea >>> r = Rectangle(5, 10) >>> print r.area 50 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 27 / 49
    139. Descriptors Properties Defining properties The built-in property(fget=None, fset=None, fdel=None, doc=None) simplifies the creation of descriptors for calculated attributes Remember that descriptors only work their magic if defined as class attributes >>> class Rectangle(object): ... \"\"\"A new-style class for representing rectangles\"\"\" ... def __init__(self, x, y): ... self.x = x ... self.y = y ... def getArea(self): ... return self.x * self.y ... area = property(fget=getArea, doc=\"Area of the rectangle\") ... del getArea >>> r = Rectangle(5, 10) >>> print r.area 50 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 27 / 49
    140. Descriptors Properties Defining properties The built-in property(fget=None, fset=None, fdel=None, doc=None) simplifies the creation of descriptors for calculated attributes Remember that descriptors only work their magic if defined as class attributes >>> class Rectangle(object): ... \"\"\"A new-style class for representing rectangles\"\"\" ... def __init__(self, x, y): ... self.x = x ... self.y = y ... def getArea(self): ... return self.x * self.y ... area = property(fget=getArea, doc=\"Area of the rectangle\") ... del getArea >>> r = Rectangle(5, 10) >>> print r.area 50 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 27 / 49
    141. Descriptors Properties A Property Implementation in Python class Property(object): \"Emulate PyProperty_Type() in Objects/descrobject.c\" def __init__(self, fget=None, fset=None, fdel=None, doc=None): self.fget = fget self.fset = fset self.fdel = fdel self.__doc__ = doc def __get__(self, obj, objtype=None): if obj is None: return self if self.fget is None: raise AttributeError, ¨nreadable attribute\" u return self.fget(obj) def __set__(self, obj, value): if self.fset is None: raise AttributeError, ¸an’t set attribute\" c self.fset(obj, value) def __delete__(self, obj): if self.fdel is None: raise AttributeError, ¸an’t delete attribute\" c self.fdel(obj) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 28 / 49
    142. Descriptors Class-Level Methods Built-in non-overriding descriptors Python supplies two built-in non-overriding descriptors types which give a class two distinct kinds of class-level methods: static method is a method you can calll on a class or on any instance without the special behaviour of the first parameter of a method class method is a method you can call on a class or on any instance and the first parameter gets bound to the class (or the object’s class) Descriptor Called from an Object Called from a Class function f(obj, *args) f(*args) staticmethod f(*args) f(*args) classmethod f(type(obj), *args) f(klass, *args) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 29 / 49
    143. Descriptors Class-Level Methods Built-in non-overriding descriptors Python supplies two built-in non-overriding descriptors types which give a class two distinct kinds of class-level methods: static method is a method you can calll on a class or on any instance without the special behaviour of the first parameter of a method class method is a method you can call on a class or on any instance and the first parameter gets bound to the class (or the object’s class) Descriptor Called from an Object Called from a Class function f(obj, *args) f(*args) staticmethod f(*args) f(*args) classmethod f(type(obj), *args) f(klass, *args) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 29 / 49
    144. Descriptors Class-Level Methods Built-in non-overriding descriptors Python supplies two built-in non-overriding descriptors types which give a class two distinct kinds of class-level methods: static method is a method you can calll on a class or on any instance without the special behaviour of the first parameter of a method class method is a method you can call on a class or on any instance and the first parameter gets bound to the class (or the object’s class) Descriptor Called from an Object Called from a Class function f(obj, *args) f(*args) staticmethod f(*args) f(*args) classmethod f(type(obj), *args) f(klass, *args) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 29 / 49
    145. Descriptors Class-Level Methods Built-in non-overriding descriptors Python supplies two built-in non-overriding descriptors types which give a class two distinct kinds of class-level methods: static method is a method you can calll on a class or on any instance without the special behaviour of the first parameter of a method class method is a method you can call on a class or on any instance and the first parameter gets bound to the class (or the object’s class) Descriptor Called from an Object Called from a Class function f(obj, *args) f(*args) staticmethod f(*args) f(*args) classmethod f(type(obj), *args) f(klass, *args) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 29 / 49
    146. Descriptors Class-Level Methods Built-in non-overriding descriptors Python supplies two built-in non-overriding descriptors types which give a class two distinct kinds of class-level methods: static method is a method you can calll on a class or on any instance without the special behaviour of the first parameter of a method class method is a method you can call on a class or on any instance and the first parameter gets bound to the class (or the object’s class) Descriptor Called from an Object Called from a Class function f(obj, *args) f(*args) staticmethod f(*args) f(*args) classmethod f(type(obj), *args) f(klass, *args) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 29 / 49
    147. Descriptors Class-Level Methods Built-in non-overriding descriptors Python supplies two built-in non-overriding descriptors types which give a class two distinct kinds of class-level methods: static method is a method you can calll on a class or on any instance without the special behaviour of the first parameter of a method class method is a method you can call on a class or on any instance and the first parameter gets bound to the class (or the object’s class) Descriptor Called from an Object Called from a Class function f(obj, *args) f(*args) staticmethod f(*args) f(*args) classmethod f(type(obj), *args) f(klass, *args) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 29 / 49
    148. Descriptors Class-Level Methods Example of Static-Method >>> class E(object): ... def f(x): ... return x ... f = staticmethod(f) ... @staticmethod ... def g(x): ... return 2*x >>> print E.f(15) 15 >>> print E().g(8) 16 J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 30 / 49
    149. Descriptors Class-Level Methods Example of Class-Method >>> class Dict(object): ... ..... ... def fromkeys(klass, iterable, value=None): ... \"Emulate dict_fromkeys() in Objects/dictobject.c\" ... d = klass() ... for key in iterable: ... d[key] = value ... return d ... fromkeys = classmethod(fromkeys) >>> Dict.fromkeys(’abracadabra’) ’a’: None, ’r’: None, ’b’: None, ’c’: None, ’d’: None J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 31 / 49
    150. Inheritance Method Resolution Order Method Resolution Order With multiple inheritance comes the question of method resolution order: the order in which a class and its basses are searched looking for a method of a given name In classic python the rule is left-to-right depth-first: def classic lookup(cls, name): \"\"\"Searches name in cls and its base classes\"\"\" if name in cls. dict : return cls. dict [name] for base in cls. bases : try: return classic lookup(base, name) except AttributeError: pass raise AttributeError, name J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 32 / 49
    151. Inheritance Method Resolution Order Method Resolution Order With multiple inheritance comes the question of method resolution order: the order in which a class and its basses are searched looking for a method of a given name In classic python the rule is left-to-right depth-first: def classic lookup(cls, name): \"\"\"Searches name in cls and its base classes\"\"\" if name in cls. dict : return cls. dict [name] for base in cls. bases : try: return classic lookup(base, name) except AttributeError: pass raise AttributeError, name J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 32 / 49
    152. Inheritance Method Resolution Order Method Resolution Order With multiple inheritance comes the question of method resolution order: the order in which a class and its basses are searched looking for a method of a given name In classic python the rule is left-to-right depth-first: def classic lookup(cls, name): \"\"\"Searches name in cls and its base classes\"\"\" if name in cls. dict : return cls. dict [name] for base in cls. bases : try: return classic lookup(base, name) except AttributeError: pass raise AttributeError, name J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 32 / 49
    153. Inheritance Method Resolution Order Method Resolution Order With multiple inheritance comes the question of method resolution order: the order in which a class and its basses are searched looking for a method of a given name In classic python the rule is left-to-right depth-first: def classic lookup(cls, name): \"\"\"Searches name in cls and its base classes\"\"\" if name in cls. dict : return cls. dict [name] for base in cls. bases : try: return classic lookup(base, name) except AttributeError: pass raise AttributeError, name J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 32 / 49
    154. Inheritance Method Resolution Order Problems with classic mro class A: This is an exemple of a diamond inheritance def save(self): diagram .... C overrides A’s save class B(A): (maybe C.save calls A.save) .... When invoking save on a D instance, A.save class C(A): is called (completedly ignoring C.save) def save(self): But in classic python diamond diagrams are .... seldom found because class D(B,C): most hierarchies use single inheritance .... multiple inheritance is usually limited to mix-in classes J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 33 / 49
    155. Inheritance Method Resolution Order Problems with classic mro class A: This is an exemple of a diamond inheritance def save(self): diagram .... C overrides A’s save class B(A): (maybe C.save calls A.save) .... When invoking save on a D instance, A.save class C(A): is called (completedly ignoring C.save) def save(self): But in classic python diamond diagrams are .... seldom found because class D(B,C): most hierarchies use single inheritance .... multiple inheritance is usually limited to mix-in classes J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 33 / 49
    156. Inheritance Method Resolution Order Problems with classic mro class A: This is an exemple of a diamond inheritance def save(self): diagram .... C overrides A’s save class B(A): (maybe C.save calls A.save) .... When invoking save on a D instance, A.save class C(A): is called (completedly ignoring C.save) def save(self): But in classic python diamond diagrams are .... seldom found because class D(B,C): most hierarchies use single inheritance .... multiple inheritance is usually limited to mix-in classes J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 33 / 49
    157. Inheritance Method Resolution Order Problems with classic mro class A: This is an exemple of a diamond inheritance def save(self): diagram .... C overrides A’s save class B(A): (maybe C.save calls A.save) .... When invoking save on a D instance, A.save class C(A): is called (completedly ignoring C.save) def save(self): But in classic python diamond diagrams are .... seldom found because class D(B,C): most hierarchies use single inheritance .... multiple inheritance is usually limited to mix-in classes J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 33 / 49
    158. Inheritance Method Resolution Order Problems with classic mro class A: This is an exemple of a diamond inheritance def save(self): diagram .... C overrides A’s save class B(A): (maybe C.save calls A.save) .... When invoking save on a D instance, A.save class C(A): is called (completedly ignoring C.save) def save(self): But in classic python diamond diagrams are .... seldom found because class D(B,C): most hierarchies use single inheritance .... multiple inheritance is usually limited to mix-in classes J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 33 / 49
    159. Inheritance Method Resolution Order Problems with classic mro class A: This is an exemple of a diamond inheritance def save(self): diagram .... C overrides A’s save class B(A): (maybe C.save calls A.save) .... When invoking save on a D instance, A.save class C(A): is called (completedly ignoring C.save) def save(self): But in classic python diamond diagrams are .... seldom found because class D(B,C): most hierarchies use single inheritance .... multiple inheritance is usually limited to mix-in classes J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 33 / 49
    160. Inheritance Method Resolution Order Problems with classic mro class A: This is an exemple of a diamond inheritance def save(self): diagram .... C overrides A’s save class B(A): (maybe C.save calls A.save) .... When invoking save on a D instance, A.save class C(A): is called (completedly ignoring C.save) def save(self): But in classic python diamond diagrams are .... seldom found because class D(B,C): most hierarchies use single inheritance .... multiple inheritance is usually limited to mix-in classes J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 33 / 49
    161. Inheritance Method Resolution Order Problems with classic mro class A: This is an exemple of a diamond inheritance def save(self): diagram .... C overrides A’s save class B(A): (maybe C.save calls A.save) .... When invoking save on a D instance, A.save class C(A): is called (completedly ignoring C.save) def save(self): But in classic python diamond diagrams are .... seldom found because class D(B,C): most hierarchies use single inheritance .... multiple inheritance is usually limited to mix-in classes J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 33 / 49
    162. Inheritance Method Resolution Order Classic MRO and New-classes In the classic model C inherits the modified behaviour of getattr But in the new model C inherits the default behaviour defined in built-in object Classic-classes class A: .... class B: def setattr (self, name, val): .... class C(A, B): .... J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 34 / 49
    163. Inheritance Method Resolution Order Classic MRO and New-classes In the classic model C inherits the modified behaviour of getattr But in the new model C inherits the default behaviour defined in built-in object New-classes # Predefined object defines the # default behaviour of getattr class A(object): .... class B(object): def setattr (self, name, val): .... class C(A, B): .... J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 34 / 49
    164. Inheritance Method Resolution Order New MRO algorithm (na¨ description) ıve Classic look-up would visit classes in this order: >>> class A(object): D, B, A, object, C, A, object ... pass New algorithm (na¨ python 2.2 ıve >>> class B(A): version) scans the list and eliminates ... pass elements repeated further in the list >>> class C(A): So, the new order is: ... pass D, B, C, A, object >>> class D(B,C): ... pass The real algorithm (since python 2.3) named C3 is described here. New-style classes get a special attribute named mro J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 35 / 49
    165. Inheritance Method Resolution Order New MRO algorithm (na¨ description) ıve Classic look-up would visit classes in this order: >>> class A(object): D, B, A, object, C, A, object ... pass New algorithm (na¨ python 2.2 ıve >>> class B(A): version) scans the list and eliminates ... pass elements repeated further in the list >>> class C(A): So, the new order is: ... pass D, B, C, A, object >>> class D(B,C): ... pass The real algorithm (since python 2.3) named C3 is described here. New-style classes get a special attribute named mro J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 35 / 49
    166. Inheritance Method Resolution Order New MRO algorithm (na¨ description) ıve Classic look-up would visit classes in this order: >>> class A(object): D, B, A, object, C, A, object ... pass New algorithm (na¨ python 2.2 ıve >>> class B(A): version) scans the list and eliminates ... pass elements repeated further in the list >>> class C(A): So, the new order is: ... pass D, B, C, A, object >>> class D(B,C): ... pass The real algorithm (since python 2.3) named C3 is described here. New-style classes get a special attribute named mro J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 35 / 49
    167. Inheritance Method Resolution Order New MRO algorithm (na¨ description) ıve Classic look-up would visit classes in this order: >>> class A(object): D, B, A, object, C, A, object ... pass New algorithm (na¨ python 2.2 ıve >>> class B(A): version) scans the list and eliminates ... pass elements repeated further in the list >>> class C(A): So, the new order is: ... pass D, B, C, A, object >>> class D(B,C): ... pass The real algorithm (since python 2.3) named C3 is described here. New-style classes get a special attribute named mro J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 35 / 49
    168. Inheritance Method Resolution Order New MRO algorithm (na¨ description) ıve Classic look-up would visit classes in this order: >>> class A(object): D, B, A, object, C, A, object ... pass New algorithm (na¨ python 2.2 ıve >>> class B(A): version) scans the list and eliminates ... pass elements repeated further in the list >>> class C(A): So, the new order is: ... pass D, B, C, A, object >>> class D(B,C): ... pass The real algorithm (since python 2.3) named C3 is described here. New-style classes get a special attribute named mro J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 35 / 49
    169. Inheritance Method Resolution Order New MRO algorithm (na¨ description) ıve Classic look-up would visit classes in this order: >>> class A(object): D, B, A, object, C, A, object ... pass New algorithm (na¨ python 2.2 ıve >>> class B(A): version) scans the list and eliminates ... pass elements repeated further in the list >>> class C(A): So, the new order is: ... pass D, B, C, A, object >>> class D(B,C): ... pass The real algorithm (since python 2.3) named C3 is described here. New-style classes get a special attribute named mro J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 35 / 49
    170. Inheritance Method Resolution Order Monotonicity and Order Disagreements Monotonicity: If class C1 precedes class >>> class A(object): C2 in the look-up order from class D, ... pass then C1 precedes C2 in the look-up >>> class B(object): order of any subclass of D ... pass Local precedence: The look-up order >>> class X(A,B): does not contradict the ordering of the ... pass bases in the class definition >>> class Y(B,A): In the example, Z’s mro would be ... pass Z, X, Y, B, A, object >>> class Z(X,Y): ... pass But X’s mro would be TypeError: ..... X, A, B, object And monotonicity would not be preserved J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 36 / 49
    171. Inheritance Method Resolution Order Monotonicity and Order Disagreements Monotonicity: If class C1 precedes class >>> class A(object): C2 in the look-up order from class D, ... pass then C1 precedes C2 in the look-up >>> class B(object): order of any subclass of D ... pass Local precedence: The look-up order >>> class X(A,B): does not contradict the ordering of the ... pass bases in the class definition >>> class Y(B,A): In the example, Z’s mro would be ... pass Z, X, Y, B, A, object >>> class Z(X,Y): ... pass But X’s mro would be TypeError: ..... X, A, B, object And monotonicity would not be preserved J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 36 / 49
    172. Inheritance Method Resolution Order Monotonicity and Order Disagreements Monotonicity: If class C1 precedes class >>> class A(object): C2 in the look-up order from class D, ... pass then C1 precedes C2 in the look-up >>> class B(object): order of any subclass of D ... pass Local precedence: The look-up order >>> class X(A,B): does not contradict the ordering of the ... pass bases in the class definition >>> class Y(B,A): In the example, Z’s mro would be ... pass Z, X, Y, B, A, object >>> class Z(X,Y): ... pass But X’s mro would be TypeError: ..... X, A, B, object And monotonicity would not be preserved J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 36 / 49
    173. Inheritance Method Resolution Order Monotonicity and Order Disagreements Monotonicity: If class C1 precedes class >>> class A(object): C2 in the look-up order from class D, ... pass then C1 precedes C2 in the look-up >>> class B(object): order of any subclass of D ... pass Local precedence: The look-up order >>> class X(A,B): does not contradict the ordering of the ... pass bases in the class definition >>> class Y(B,A): In the example, Z’s mro would be ... pass Z, X, Y, B, A, object >>> class Z(X,Y): ... pass But X’s mro would be TypeError: ..... X, A, B, object And monotonicity would not be preserved J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 36 / 49
    174. Inheritance Method Resolution Order Monotonicity and Order Disagreements Monotonicity: If class C1 precedes class >>> class A(object): C2 in the look-up order from class D, ... pass then C1 precedes C2 in the look-up >>> class B(object): order of any subclass of D ... pass Local precedence: The look-up order >>> class X(A,B): does not contradict the ordering of the ... pass bases in the class definition >>> class Y(B,A): In the example, Z’s mro would be ... pass Z, X, Y, B, A, object >>> class Z(X,Y): ... pass But X’s mro would be TypeError: ..... X, A, B, object And monotonicity would not be preserved J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 36 / 49
    175. Inheritance Method Resolution Order Monotonicity and Order Disagreements Monotonicity: If class C1 precedes class >>> class A(object): C2 in the look-up order from class D, ... pass then C1 precedes C2 in the look-up >>> class B(object): order of any subclass of D ... pass Local precedence: The look-up order >>> class X(A,B): does not contradict the ordering of the ... pass bases in the class definition >>> class Y(B,A): In the example, Z’s mro would be ... pass Z, X, Y, B, A, object >>> class Z(X,Y): ... pass But X’s mro would be TypeError: ..... X, A, B, object And monotonicity would not be preserved J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 36 / 49
    176. Inheritance Cooperative Superclasses Cooperative super call This is one of the coolest and one of the most unusual features of the new-class model Cooperative classes are written with multiple inheritance in mind, using a pattern known in other languages as call-next-method It is more powerfull than the super call found in single-inheritance language such as Java First, let’s review the traditional non-coperative super call: class A(object): def m(self): print \"Saving A’s data\" class B(A): def m(self): print \"Saving B’s data\" A.m(self) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 37 / 49
    177. Inheritance Cooperative Superclasses Cooperative super call This is one of the coolest and one of the most unusual features of the new-class model Cooperative classes are written with multiple inheritance in mind, using a pattern known in other languages as call-next-method It is more powerfull than the super call found in single-inheritance language such as Java First, let’s review the traditional non-coperative super call: class A(object): def m(self): print \"Saving A’s data\" class B(A): def m(self): print \"Saving B’s data\" A.m(self) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 37 / 49
    178. Inheritance Cooperative Superclasses Cooperative super call This is one of the coolest and one of the most unusual features of the new-class model Cooperative classes are written with multiple inheritance in mind, using a pattern known in other languages as call-next-method It is more powerfull than the super call found in single-inheritance language such as Java First, let’s review the traditional non-coperative super call: class A(object): def m(self): print \"Saving A’s data\" class B(A): def m(self): print \"Saving B’s data\" A.m(self) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 37 / 49
    179. Inheritance Cooperative Superclasses Cooperative super call This is one of the coolest and one of the most unusual features of the new-class model Cooperative classes are written with multiple inheritance in mind, using a pattern known in other languages as call-next-method It is more powerfull than the super call found in single-inheritance language such as Java First, let’s review the traditional non-coperative super call: class A(object): def m(self): print \"Saving A’s data\" class B(A): def m(self): print \"Saving B’s data\" A.m(self) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 37 / 49
    180. Inheritance Cooperative Superclasses Cooperative super call This is one of the coolest and one of the most unusual features of the new-class model Cooperative classes are written with multiple inheritance in mind, using a pattern known in other languages as call-next-method It is more powerfull than the super call found in single-inheritance language such as Java First, let’s review the traditional non-coperative super call: class A(object): def m(self): print \"Saving A’s data\" class B(A): def m(self): print \"Saving B’s data\" A.m(self) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 37 / 49
    181. Inheritance Cooperative Superclasses Cooperative super call This is one of the coolest and one of the most unusual features of the new-class model Cooperative classes are written with multiple inheritance in mind, using a pattern known in other languages as call-next-method It is more powerfull than the super call found in single-inheritance language such as Java First, let’s review the traditional non-coperative super call: class A(object): def m(self): print \"Saving A’s data\" class B(A): def m(self): print \"Saving B’s data\" A.m(self) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 37 / 49
    182. Inheritance Cooperative Superclasses Non-cooperative super and multiple inheritance class A(object): def m(self): print \"Saving A’s data\" class B(A): def m(self): This example is a case of print \"Saving B’s data\" diamond inheritance A.m(self) diagram class C(A): def m(self): A.m gets called twice !!! print \"Saving C’s data\" at best this is A.m(self) inefficient class D(B, C): at worst it is an error def m(self): print \"Saving D’s data\" B.m(self) C.m(self) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 38 / 49
    183. Inheritance Cooperative Superclasses Non-cooperative super and multiple inheritance class A(object): def m(self): print \"Saving A’s data\" class B(A): def m(self): This example is a case of print \"Saving B’s data\" diamond inheritance A.m(self) diagram class C(A): def m(self): A.m gets called twice !!! print \"Saving C’s data\" at best this is A.m(self) inefficient class D(B, C): at worst it is an error def m(self): print \"Saving D’s data\" B.m(self) C.m(self) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 38 / 49
    184. Inheritance Cooperative Superclasses Non-cooperative super and multiple inheritance class A(object): def m(self): print \"Saving A’s data\" class B(A): def m(self): This example is a case of print \"Saving B’s data\" diamond inheritance A.m(self) diagram class C(A): def m(self): A.m gets called twice !!! print \"Saving C’s data\" at best this is A.m(self) inefficient class D(B, C): at worst it is an error def m(self): print \"Saving D’s data\" B.m(self) C.m(self) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 38 / 49
    185. Inheritance Cooperative Superclasses Non-cooperative super and multiple inheritance class A(object): def m(self): print \"Saving A’s data\" class B(A): def m(self): This example is a case of print \"Saving B’s data\" diamond inheritance A.m(self) diagram class C(A): def m(self): A.m gets called twice !!! print \"Saving C’s data\" at best this is A.m(self) inefficient class D(B, C): at worst it is an error def m(self): print \"Saving D’s data\" B.m(self) C.m(self) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 38 / 49
    186. Inheritance Cooperative Superclasses Non-cooperative super and multiple inheritance class A(object): def m(self): print \"Saving A’s data\" class B(A): def m(self): This example is a case of print \"Saving B’s data\" diamond inheritance A.m(self) diagram class C(A): def m(self): A.m gets called twice !!! print \"Saving C’s data\" at best this is A.m(self) inefficient class D(B, C): at worst it is an error def m(self): print \"Saving D’s data\" B.m(self) C.m(self) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 38 / 49
    187. Inheritance Cooperative Superclasses Traditional ¿solution? class A(object): def _m(self): print \"Saving A’s data\" def m(self): self._m() class B(A): def _m(self): print \"Saving B’s data\" def m(self): self._m(); A._m(self) class C(A): def _m(self): print \"Saving C’s data\" def m(self): self._m(); A._m(self) class D(B, C): def _m(self): print \"Saving D’s data\" def m(self): self._m(); B._m(self); C._m(self); A._m(self) The proliferation of extra methods and calls is a problem It creates an undesisable dependency in the derived classes on the details of the inheritance graph of its base classes J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 39 / 49
    188. Inheritance Cooperative Superclasses Traditional ¿solution? class A(object): def _m(self): print \"Saving A’s data\" def m(self): self._m() class B(A): def _m(self): print \"Saving B’s data\" def m(self): self._m(); A._m(self) class C(A): def _m(self): print \"Saving C’s data\" def m(self): self._m(); A._m(self) class D(B, C): def _m(self): print \"Saving D’s data\" def m(self): self._m(); B._m(self); C._m(self); A._m(self) The proliferation of extra methods and calls is a problem It creates an undesisable dependency in the derived classes on the details of the inheritance graph of its base classes J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 39 / 49
    189. Inheritance Cooperative Superclasses Traditional ¿solution? class A(object): def _m(self): print \"Saving A’s data\" def m(self): self._m() class B(A): def _m(self): print \"Saving B’s data\" def m(self): self._m(); A._m(self) class C(A): def _m(self): print \"Saving C’s data\" def m(self): self._m(); A._m(self) class D(B, C): def _m(self): print \"Saving D’s data\" def m(self): self._m(); B._m(self); C._m(self); A._m(self) The proliferation of extra methods and calls is a problem It creates an undesisable dependency in the derived classes on the details of the inheritance graph of its base classes J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 39 / 49
    190. Inheritance Cooperative Superclasses Using cooperative super class A(object): def m(self): print \"Saving A’s data\" class B(A): def m(self): print \"Saving B’s data\"; super(B, self).m() class C(A): def m(self): print \"Saving C’s data\"; super(C, self).m() class D(B, C): def m(self): print \"Saving D’s data\"; super(D, self).m() the first argument to super is the class in which it occurs the second is always self (and it is not repeated in the argument list) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 40 / 49
    191. Inheritance Cooperative Superclasses Using cooperative super class A(object): def m(self): print \"Saving A’s data\" class B(A): def m(self): print \"Saving B’s data\"; super(B, self).m() class C(A): def m(self): print \"Saving C’s data\"; super(C, self).m() class D(B, C): def m(self): print \"Saving D’s data\"; super(D, self).m() the first argument to super is the class in which it occurs the second is always self (and it is not repeated in the argument list) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 40 / 49
    192. Inheritance Cooperative Superclasses Using cooperative super class A(object): def m(self): print \"Saving A’s data\" class B(A): def m(self): print \"Saving B’s data\"; super(B, self).m() class C(A): def m(self): print \"Saving C’s data\"; super(C, self).m() class D(B, C): def m(self): print \"Saving D’s data\"; super(D, self).m() the first argument to super is the class in which it occurs the second is always self (and it is not repeated in the argument list) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 40 / 49
    193. Inheritance Cooperative Superclasses How does super work? Consider the MRO of each of the classes A. mro == (A, object) B. mro == (B, A, object) C. mro == (C, A, object) D. mro == (D, B, C, A, object) super(C, self) should only be used inside the implementation of methods in class C self is an instance of C self. class may not be C but one of the classes derived from C The expression super(C, self).m 1 first, searches self. class . mro for C 2 and then, starts looking for an implementation of m following that point (super(class, subclass) also works to allow cooperative new and other static methods. It uses subclass. mro in the first step.) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 41 / 49
    194. Inheritance Cooperative Superclasses How does super work? Consider the MRO of each of the classes A. mro == (A, object) B. mro == (B, A, object) C. mro == (C, A, object) D. mro == (D, B, C, A, object) super(C, self) should only be used inside the implementation of methods in class C self is an instance of C self. class may not be C but one of the classes derived from C The expression super(C, self).m 1 first, searches self. class . mro for C 2 and then, starts looking for an implementation of m following that point (super(class, subclass) also works to allow cooperative new and other static methods. It uses subclass. mro in the first step.) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 41 / 49
    195. Inheritance Cooperative Superclasses How does super work? Consider the MRO of each of the classes A. mro == (A, object) B. mro == (B, A, object) C. mro == (C, A, object) D. mro == (D, B, C, A, object) super(C, self) should only be used inside the implementation of methods in class C self is an instance of C self. class may not be C but one of the classes derived from C The expression super(C, self).m 1 first, searches self. class . mro for C 2 and then, starts looking for an implementation of m following that point (super(class, subclass) also works to allow cooperative new and other static methods. It uses subclass. mro in the first step.) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 41 / 49
    196. Inheritance Cooperative Superclasses How does super work? Consider the MRO of each of the classes A. mro == (A, object) B. mro == (B, A, object) C. mro == (C, A, object) D. mro == (D, B, C, A, object) super(C, self) should only be used inside the implementation of methods in class C self is an instance of C self. class may not be C but one of the classes derived from C The expression super(C, self).m 1 first, searches self. class . mro for C 2 and then, starts looking for an implementation of m following that point (super(class, subclass) also works to allow cooperative new and other static methods. It uses subclass. mro in the first step.) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 41 / 49
    197. Inheritance Cooperative Superclasses How does super work? Consider the MRO of each of the classes A. mro == (A, object) B. mro == (B, A, object) C. mro == (C, A, object) D. mro == (D, B, C, A, object) super(C, self) should only be used inside the implementation of methods in class C self is an instance of C self. class may not be C but one of the classes derived from C The expression super(C, self).m 1 first, searches self. class . mro for C 2 and then, starts looking for an implementation of m following that point (super(class, subclass) also works to allow cooperative new and other static methods. It uses subclass. mro in the first step.) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 41 / 49
    198. Inheritance Cooperative Superclasses How does super work? Consider the MRO of each of the classes A. mro == (A, object) B. mro == (B, A, object) C. mro == (C, A, object) D. mro == (D, B, C, A, object) super(C, self) should only be used inside the implementation of methods in class C self is an instance of C self. class may not be C but one of the classes derived from C The expression super(C, self).m 1 first, searches self. class . mro for C 2 and then, starts looking for an implementation of m following that point (super(class, subclass) also works to allow cooperative new and other static methods. It uses subclass. mro in the first step.) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 41 / 49
    199. Inheritance Cooperative Superclasses How does super work? Consider the MRO of each of the classes A. mro == (A, object) B. mro == (B, A, object) C. mro == (C, A, object) D. mro == (D, B, C, A, object) super(C, self) should only be used inside the implementation of methods in class C self is an instance of C self. class may not be C but one of the classes derived from C The expression super(C, self).m 1 first, searches self. class . mro for C 2 and then, starts looking for an implementation of m following that point (super(class, subclass) also works to allow cooperative new and other static methods. It uses subclass. mro in the first step.) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 41 / 49
    200. Inheritance Cooperative Superclasses How does super work? Consider the MRO of each of the classes A. mro == (A, object) B. mro == (B, A, object) C. mro == (C, A, object) D. mro == (D, B, C, A, object) super(C, self) should only be used inside the implementation of methods in class C self is an instance of C self. class may not be C but one of the classes derived from C The expression super(C, self).m 1 first, searches self. class . mro for C 2 and then, starts looking for an implementation of m following that point (super(class, subclass) also works to allow cooperative new and other static methods. It uses subclass. mro in the first step.) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 41 / 49
    201. Inheritance Cooperative Superclasses How does super work? Consider the MRO of each of the classes A. mro == (A, object) B. mro == (B, A, object) C. mro == (C, A, object) D. mro == (D, B, C, A, object) super(C, self) should only be used inside the implementation of methods in class C self is an instance of C self. class may not be C but one of the classes derived from C The expression super(C, self).m 1 first, searches self. class . mro for C 2 and then, starts looking for an implementation of m following that point (super(class, subclass) also works to allow cooperative new and other static methods. It uses subclass. mro in the first step.) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 41 / 49
    202. Inheritance Cooperative Superclasses How does super work? Consider the MRO of each of the classes A. mro == (A, object) B. mro == (B, A, object) C. mro == (C, A, object) D. mro == (D, B, C, A, object) super(C, self) should only be used inside the implementation of methods in class C self is an instance of C self. class may not be C but one of the classes derived from C The expression super(C, self).m 1 first, searches self. class . mro for C 2 and then, starts looking for an implementation of m following that point (super(class, subclass) also works to allow cooperative new and other static methods. It uses subclass. mro in the first step.) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 41 / 49
    203. Inheritance Cooperative Superclasses Implementing super in Python class Super(object): def __init__(self, type, obj=None): self.__type__ = type self.__obj__ = obj def __getattr__(self, attr): if isinstance(self.__obj__, self.__type__): startype = self.__obj__.__class__ else: startype = self.__obj__ mro = iter(startype.__mro__) for cls in mro: if cls is self.__type__: break # mro is an iterator, so the second loop picks # up where the first one left out for cls in mro: if attr in cls.__dict__: x = cls.__dict__[attr] if hasattr(x, \"__get__\"): x = x.__get__(self.__obj__) return x raise AttributteError, attr J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 42 / 49
    204. Instances II Creating Instances 2 Each new-style class has (or inherits) a static method named new When you do x = C(*args, **kwargs) Python executes: (link to Metaclasses: this code is in type(C). call ) x = C.__new__(C, *args, **kwargs) if isinstance(x, C): type(x).__init__(x, *args, **kwargs) The predefined object. new : creates a new, uninitialized instance of the class it receives as its first argument it ignores other arguments if that class has (or inherits) an init method it raises an exception if it receives other arguments beyond the first but the class does not have an init method When you override new inside the class it is not necesary to add new = staticmethod( new ) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 43 / 49
    205. Instances II Creating Instances 2 Each new-style class has (or inherits) a static method named new When you do x = C(*args, **kwargs) Python executes: (link to Metaclasses: this code is in type(C). call ) x = C.__new__(C, *args, **kwargs) if isinstance(x, C): type(x).__init__(x, *args, **kwargs) The predefined object. new : creates a new, uninitialized instance of the class it receives as its first argument it ignores other arguments if that class has (or inherits) an init method it raises an exception if it receives other arguments beyond the first but the class does not have an init method When you override new inside the class it is not necesary to add new = staticmethod( new ) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 43 / 49
    206. Instances II Creating Instances 2 Each new-style class has (or inherits) a static method named new When you do x = C(*args, **kwargs) Python executes: (link to Metaclasses: this code is in type(C). call ) x = C.__new__(C, *args, **kwargs) if isinstance(x, C): type(x).__init__(x, *args, **kwargs) The predefined object. new : creates a new, uninitialized instance of the class it receives as its first argument it ignores other arguments if that class has (or inherits) an init method it raises an exception if it receives other arguments beyond the first but the class does not have an init method When you override new inside the class it is not necesary to add new = staticmethod( new ) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 43 / 49
    207. Instances II Creating Instances 2 Each new-style class has (or inherits) a static method named new When you do x = C(*args, **kwargs) Python executes: (link to Metaclasses: this code is in type(C). call ) x = C.__new__(C, *args, **kwargs) if isinstance(x, C): type(x).__init__(x, *args, **kwargs) The predefined object. new : creates a new, uninitialized instance of the class it receives as its first argument it ignores other arguments if that class has (or inherits) an init method it raises an exception if it receives other arguments beyond the first but the class does not have an init method When you override new inside the class it is not necesary to add new = staticmethod( new ) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 43 / 49
    208. Instances II Creating Instances 2 Each new-style class has (or inherits) a static method named new When you do x = C(*args, **kwargs) Python executes: (link to Metaclasses: this code is in type(C). call ) x = C.__new__(C, *args, **kwargs) if isinstance(x, C): type(x).__init__(x, *args, **kwargs) The predefined object. new : creates a new, uninitialized instance of the class it receives as its first argument it ignores other arguments if that class has (or inherits) an init method it raises an exception if it receives other arguments beyond the first but the class does not have an init method When you override new inside the class it is not necesary to add new = staticmethod( new ) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 43 / 49
    209. Instances II Creating Instances 2 Each new-style class has (or inherits) a static method named new When you do x = C(*args, **kwargs) Python executes: (link to Metaclasses: this code is in type(C). call ) x = C.__new__(C, *args, **kwargs) if isinstance(x, C): type(x).__init__(x, *args, **kwargs) The predefined object. new : creates a new, uninitialized instance of the class it receives as its first argument it ignores other arguments if that class has (or inherits) an init method it raises an exception if it receives other arguments beyond the first but the class does not have an init method When you override new inside the class it is not necesary to add new = staticmethod( new ) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 43 / 49
    210. Instances II Creating Instances 2 Each new-style class has (or inherits) a static method named new When you do x = C(*args, **kwargs) Python executes: (link to Metaclasses: this code is in type(C). call ) x = C.__new__(C, *args, **kwargs) if isinstance(x, C): type(x).__init__(x, *args, **kwargs) The predefined object. new : creates a new, uninitialized instance of the class it receives as its first argument it ignores other arguments if that class has (or inherits) an init method it raises an exception if it receives other arguments beyond the first but the class does not have an init method When you override new inside the class it is not necesary to add new = staticmethod( new ) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 43 / 49
    211. Instances II Creating Instances 2 Each new-style class has (or inherits) a static method named new When you do x = C(*args, **kwargs) Python executes: (link to Metaclasses: this code is in type(C). call ) x = C.__new__(C, *args, **kwargs) if isinstance(x, C): type(x).__init__(x, *args, **kwargs) The predefined object. new : creates a new, uninitialized instance of the class it receives as its first argument it ignores other arguments if that class has (or inherits) an init method it raises an exception if it receives other arguments beyond the first but the class does not have an init method When you override new inside the class it is not necesary to add new = staticmethod( new ) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 43 / 49
    212. Instances II Creating Instances 2 Each new-style class has (or inherits) a static method named new When you do x = C(*args, **kwargs) Python executes: (link to Metaclasses: this code is in type(C). call ) x = C.__new__(C, *args, **kwargs) if isinstance(x, C): type(x).__init__(x, *args, **kwargs) The predefined object. new : creates a new, uninitialized instance of the class it receives as its first argument it ignores other arguments if that class has (or inherits) an init method it raises an exception if it receives other arguments beyond the first but the class does not have an init method When you override new inside the class it is not necesary to add new = staticmethod( new ) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 43 / 49
    213. Instances II Creating Instances 2 Each new-style class has (or inherits) a static method named new When you do x = C(*args, **kwargs) Python executes: (link to Metaclasses: this code is in type(C). call ) x = C.__new__(C, *args, **kwargs) if isinstance(x, C): type(x).__init__(x, *args, **kwargs) The predefined object. new : creates a new, uninitialized instance of the class it receives as its first argument it ignores other arguments if that class has (or inherits) an init method it raises an exception if it receives other arguments beyond the first but the class does not have an init method When you override new inside the class it is not necesary to add new = staticmethod( new ) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 43 / 49
    214. Instances II Creating Instances 2 Each new-style class has (or inherits) a static method named new When you do x = C(*args, **kwargs) Python executes: (link to Metaclasses: this code is in type(C). call ) x = C.__new__(C, *args, **kwargs) if isinstance(x, C): type(x).__init__(x, *args, **kwargs) The predefined object. new : creates a new, uninitialized instance of the class it receives as its first argument it ignores other arguments if that class has (or inherits) an init method it raises an exception if it receives other arguments beyond the first but the class does not have an init method When you override new inside the class it is not necesary to add new = staticmethod( new ) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 43 / 49
    215. Instances II Subclassing immutable built-in Does not work !!! It works !!! class inch(float): class inch(float): \"Converts from inch to meter\" \"Converts from inch to meter\" def __init__(cls, arg=0.0): def __new__(cls, arg=0.0): return float.__init__(cls, return float.__new__(cls, arg*0.0254) arg*0.0254) print inch(12) # prints 12 print inch(12) # prints 0.3048 float. init ignores its arguments to preserve immutability Types which ignore init ’s arguments: int, long, float, complex, str, unicode, tuple Types which ignore new ’s arguments: dict, list, file, super, classmethod, staticmethod, property Built-in type object ignores extra arguments in both methods Built-in type type is special in many respects J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 44 / 49
    216. Instances II Subclassing immutable built-in Does not work !!! It works !!! class inch(float): class inch(float): \"Converts from inch to meter\" \"Converts from inch to meter\" def __init__(cls, arg=0.0): def __new__(cls, arg=0.0): return float.__init__(cls, return float.__new__(cls, arg*0.0254) arg*0.0254) print inch(12) # prints 12 print inch(12) # prints 0.3048 float. init ignores its arguments to preserve immutability Types which ignore init ’s arguments: int, long, float, complex, str, unicode, tuple Types which ignore new ’s arguments: dict, list, file, super, classmethod, staticmethod, property Built-in type object ignores extra arguments in both methods Built-in type type is special in many respects J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 44 / 49
    217. Instances II Subclassing immutable built-in Does not work !!! It works !!! class inch(float): class inch(float): \"Converts from inch to meter\" \"Converts from inch to meter\" def __init__(cls, arg=0.0): def __new__(cls, arg=0.0): return float.__init__(cls, return float.__new__(cls, arg*0.0254) arg*0.0254) print inch(12) # prints 12 print inch(12) # prints 0.3048 float. init ignores its arguments to preserve immutability Types which ignore init ’s arguments: int, long, float, complex, str, unicode, tuple Types which ignore new ’s arguments: dict, list, file, super, classmethod, staticmethod, property Built-in type object ignores extra arguments in both methods Built-in type type is special in many respects J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 44 / 49
    218. Instances II Subclassing immutable built-in Does not work !!! It works !!! class inch(float): class inch(float): \"Converts from inch to meter\" \"Converts from inch to meter\" def __init__(cls, arg=0.0): def __new__(cls, arg=0.0): return float.__init__(cls, return float.__new__(cls, arg*0.0254) arg*0.0254) print inch(12) # prints 12 print inch(12) # prints 0.3048 float. init ignores its arguments to preserve immutability Types which ignore init ’s arguments: int, long, float, complex, str, unicode, tuple Types which ignore new ’s arguments: dict, list, file, super, classmethod, staticmethod, property Built-in type object ignores extra arguments in both methods Built-in type type is special in many respects J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 44 / 49
    219. Instances II Subclassing immutable built-in Does not work !!! It works !!! class inch(float): class inch(float): \"Converts from inch to meter\" \"Converts from inch to meter\" def __init__(cls, arg=0.0): def __new__(cls, arg=0.0): return float.__init__(cls, return float.__new__(cls, arg*0.0254) arg*0.0254) print inch(12) # prints 12 print inch(12) # prints 0.3048 float. init ignores its arguments to preserve immutability Types which ignore init ’s arguments: int, long, float, complex, str, unicode, tuple Types which ignore new ’s arguments: dict, list, file, super, classmethod, staticmethod, property Built-in type object ignores extra arguments in both methods Built-in type type is special in many respects J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 44 / 49
    220. Instances II Subclassing immutable built-in Does not work !!! It works !!! class inch(float): class inch(float): \"Converts from inch to meter\" \"Converts from inch to meter\" def __init__(cls, arg=0.0): def __new__(cls, arg=0.0): return float.__init__(cls, return float.__new__(cls, arg*0.0254) arg*0.0254) print inch(12) # prints 12 print inch(12) # prints 0.3048 float. init ignores its arguments to preserve immutability Types which ignore init ’s arguments: int, long, float, complex, str, unicode, tuple Types which ignore new ’s arguments: dict, list, file, super, classmethod, staticmethod, property Built-in type object ignores extra arguments in both methods Built-in type type is special in many respects J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 44 / 49
    221. Instances II Subclassing immutable built-in Does not work !!! It works !!! class inch(float): class inch(float): \"Converts from inch to meter\" \"Converts from inch to meter\" def __init__(cls, arg=0.0): def __new__(cls, arg=0.0): return float.__init__(cls, return float.__new__(cls, arg*0.0254) arg*0.0254) print inch(12) # prints 12 print inch(12) # prints 0.3048 float. init ignores its arguments to preserve immutability Types which ignore init ’s arguments: int, long, float, complex, str, unicode, tuple Types which ignore new ’s arguments: dict, list, file, super, classmethod, staticmethod, property Built-in type object ignores extra arguments in both methods Built-in type type is special in many respects J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 44 / 49
    222. Instances II Some rules for new A new method that overrides base class’s new may call that base class’s new method In doing so, the first argument in the call must be the class argument to the overriding new and not the base class Unless you want to do caching, new ’s only way to create an instance is to call base class’s new subclass’s new can pass different arguments to the base class’s new , or modify the resulting object after it is created by the call new ’s must return an object but there’s nothing that requires it to be a new object nor an instance of its class argument J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 45 / 49
    223. Instances II Some rules for new A new method that overrides base class’s new may call that base class’s new method In doing so, the first argument in the call must be the class argument to the overriding new and not the base class Unless you want to do caching, new ’s only way to create an instance is to call base class’s new subclass’s new can pass different arguments to the base class’s new , or modify the resulting object after it is created by the call new ’s must return an object but there’s nothing that requires it to be a new object nor an instance of its class argument J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 45 / 49
    224. Instances II Some rules for new A new method that overrides base class’s new may call that base class’s new method In doing so, the first argument in the call must be the class argument to the overriding new and not the base class Unless you want to do caching, new ’s only way to create an instance is to call base class’s new subclass’s new can pass different arguments to the base class’s new , or modify the resulting object after it is created by the call new ’s must return an object but there’s nothing that requires it to be a new object nor an instance of its class argument J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 45 / 49
    225. Instances II Some rules for new A new method that overrides base class’s new may call that base class’s new method In doing so, the first argument in the call must be the class argument to the overriding new and not the base class Unless you want to do caching, new ’s only way to create an instance is to call base class’s new subclass’s new can pass different arguments to the base class’s new , or modify the resulting object after it is created by the call new ’s must return an object but there’s nothing that requires it to be a new object nor an instance of its class argument J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 45 / 49
    226. Instances II Some rules for new A new method that overrides base class’s new may call that base class’s new method In doing so, the first argument in the call must be the class argument to the overriding new and not the base class Unless you want to do caching, new ’s only way to create an instance is to call base class’s new subclass’s new can pass different arguments to the base class’s new , or modify the resulting object after it is created by the call new ’s must return an object but there’s nothing that requires it to be a new object nor an instance of its class argument J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 45 / 49
    227. Instances II Some rules for new A new method that overrides base class’s new may call that base class’s new method In doing so, the first argument in the call must be the class argument to the overriding new and not the base class Unless you want to do caching, new ’s only way to create an instance is to call base class’s new subclass’s new can pass different arguments to the base class’s new , or modify the resulting object after it is created by the call new ’s must return an object but there’s nothing that requires it to be a new object nor an instance of its class argument J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 45 / 49
    228. Instances II A version of the Singleton Pattern class Singleton(object): _singletons = {} def __new__(cls, *args, **kwargs): if cls not in cls._singletons: cls._singletons[cls] = \\ super(Singleton, cls).__new__(cls, *args, **kwargs) return cls._singletons[cls] Any subclass of Singleton which does not override new has at most one instance If the subclass defines an init method it must be idempotent (safe when called repeatedly) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 46 / 49
    229. Instances II A version of the Singleton Pattern class Singleton(object): _singletons = {} def __new__(cls, *args, **kwargs): if cls not in cls._singletons: cls._singletons[cls] = \\ super(Singleton, cls).__new__(cls, *args, **kwargs) return cls._singletons[cls] Any subclass of Singleton which does not override new has at most one instance If the subclass defines an init method it must be idempotent (safe when called repeatedly) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 46 / 49
    230. Instances II A version of the Singleton Pattern class Singleton(object): _singletons = {} def __new__(cls, *args, **kwargs): if cls not in cls._singletons: cls._singletons[cls] = \\ super(Singleton, cls).__new__(cls, *args, **kwargs) return cls._singletons[cls] Any subclass of Singleton which does not override new has at most one instance If the subclass defines an init method it must be idempotent (safe when called repeatedly) J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 46 / 49
    231. Exercicies Hands-on work 1 Implement a class for a ring-buffer with a fixed size so that, when ot fills up, adding another element overwrites the oldest. It has three methods: init (self, size max), append(self, x) and tolist(self) 2 Implement a binary-search-tree class. Include a method for an in-order traversal (returning a list of elements) 3 Implement the Rectangle class modifying (i) getattr (ii) getattribute 4 Implement descriptor classes with the same behaviour of classmethod and staticmethod J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 47 / 49
    232. Bibliography Bibliography Raymond Hettinger, How-to Guide for Descriptors Michael Hudson, OOP in Python after 2.2 (or Fun with Descriptors), PythonUK (part of the ACCU Conference), 2004. Alex Martelli, Python in a Nutshell (2nd Edition), O’Reilly Media Inc, 2006. Michele Simionato, The Python 2.3 Method Resolution Order Guido Van Rossum, Unifying types and classes in Python 2.2 Guido Van Rossum, PEP-252: Making types look more like classes Guido Van Rossum, PEP-253: Subtyping built-in types J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 48 / 49
    233. License License Aquesta obra est` subjecta a una llic`ncia Reconeixement-Compartir amb a e la mateixa llic`ncia 2.5 Espanya de Creative Commons. e Per veure’n una c`pia, visiteu o http://creativecommons.org/licenses/by-sa/2.5/es/ o envieu una carta a Creative Commons 559 Nathan Abbott Way Stanford California 94305 USA J.M.Gimeno (jmgimeno@diei.udl.cat) OOP in Python Curs 2007-2008 49 / 49

    + Juan-Manuel GimenoJuan-Manuel Gimeno, 6 months ago

    custom

    573 views, 5 favs, 1 embeds more stats

    A description of the mechanisms that allow object-o more

    More info about this document

    CC Attribution-ShareAlike LicenseCC Attribution-ShareAlike License

    Go to text version

    • Total Views 573
      • 571 on SlideShare
      • 2 from embeds
    • Comments 0
    • Favorites 5
    • Downloads 0
    Most viewed embeds
    • 2 views on https://confluence.uk.jpmorgan.com

    more

    All embeds
    • 2 views on https://confluence.uk.jpmorgan.com

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories