SlideShare a Scribd company logo
Object Oriented Programming in Python

                                     Juan Manuel Gimeno Illa
                                       jmgimeno@diei.udl.cat

                                         Curs 2009-2010




J.M.Gimeno (jmgimeno@diei.udl.cat)          OOP in Python      Curs 2009-2010   1 / 49
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 2009-2010   2 / 49
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 2009-2010   3 / 49
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 2009-2010   3 / 49
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 2009-2010   3 / 49
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 2009-2010   3 / 49
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 2009-2010   3 / 49
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 2009-2010   3 / 49
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 2009-2010   3 / 49
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 2009-2010   3 / 49
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 2009-2010   4 / 49
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 2009-2010   4 / 49
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 2009-2010   4 / 49
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 2009-2010   4 / 49
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 2009-2010   4 / 49
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 2009-2010   4 / 49
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 2009-2010   5 / 49
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 2009-2010   5 / 49
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 2009-2010   5 / 49
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 2009-2010   5 / 49
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 2009-2010   5 / 49
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 2009-2010   6 / 49
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 2009-2010   6 / 49
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 2009-2010   6 / 49
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 2009-2010   6 / 49
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 2009-2010   6 / 49
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 2009-2010   6 / 49
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 2009-2010   6 / 49
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 2009-2010   6 / 49
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 2009-2010   6 / 49
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 2009-2010   6 / 49
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 2009-2010   6 / 49
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 2009-2010   6 / 49
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 2009-2010   6 / 49
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 2009-2010   7 / 49
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 2009-2010   7 / 49
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 2009-2010   7 / 49
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 2009-2010   7 / 49
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 2009-2010   7 / 49
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 2009-2010   7 / 49
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 2009-2010   7 / 49
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 2009-2010   7 / 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 2009-2010   8 / 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 2009-2010   8 / 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 2009-2010   8 / 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 2009-2010   8 / 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 2009-2010   8 / 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 2009-2010   8 / 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 2009-2010   8 / 49
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 2009-2010   9 / 49
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 2009-2010   9 / 49
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 2009-2010   9 / 49
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 2009-2010   9 / 49
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 2009-2010   9 / 49
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 2009-2010   9 / 49
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 2009-2010   9 / 49
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 2009-2010   9 / 49
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 2009-2010   9 / 49
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 2009-2010   10 / 49
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 2009-2010   10 / 49
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 2009-2010   10 / 49
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 2009-2010   10 / 49
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 2009-2010   11 / 49
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 2009-2010   11 / 49
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 2009-2010   11 / 49
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 2009-2010   11 / 49
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 2009-2010   12 / 49
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 2009-2010   12 / 49
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 2009-2010   12 / 49
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 2009-2010   12 / 49
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 2009-2010   12 / 49
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 2009-2010   12 / 49
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 2009-2010   12 / 49
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 2009-2010   12 / 49
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 2009-2010   12 / 49
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 2009-2010   12 / 49
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 2009-2010   12 / 49
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 2009-2010   12 / 49
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 2009-2010   12 / 49
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 2009-2010   13 / 49
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 2009-2010   13 / 49
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 2009-2010   13 / 49
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 2009-2010   13 / 49
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 2009-2010   13 / 49
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 2009-2010   13 / 49
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 2009-2010   13 / 49
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 2009-2010   14 / 49
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 2009-2010   14 / 49
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 2009-2010   14 / 49
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 2009-2010   14 / 49
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 2009-2010   14 / 49
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 2009-2010   14 / 49
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 2009-2010   14 / 49
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 2009-2010   15 / 49
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 2009-2010   16 / 49
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 2009-2010   16 / 49
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 2009-2010   16 / 49
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 2009-2010   16 / 49
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 2009-2010   17 / 49
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 2009-2010   17 / 49
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 2009-2010   17 / 49
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 2009-2010   17 / 49
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 2009-2010   17 / 49
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 2009-2010   17 / 49
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 2009-2010   17 / 49
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 2009-2010   18 / 49
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 2009-2010   18 / 49
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 2009-2010   18 / 49
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 2009-2010   18 / 49
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 2009-2010   18 / 49
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 2009-2010   18 / 49
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 2009-2010   19 / 49
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 2009-2010   19 / 49
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 2009-2010   19 / 49
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 2009-2010   20 / 49
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 2009-2010   20 / 49
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 2009-2010   20 / 49
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 2009-2010   20 / 49
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 2009-2010   21 / 49
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 2009-2010   22 / 49
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 2009-2010   22 / 49
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 2009-2010   22 / 49
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 2009-2010   22 / 49
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 2009-2010   22 / 49
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 2009-2010   22 / 49
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 2009-2010   23 / 49
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 2009-2010   23 / 49
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 2009-2010   23 / 49
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 2009-2010   23 / 49
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 2009-2010   23 / 49
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 2009-2010   23 / 49
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 2009-2010   24 / 49
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 2009-2010   25 / 49
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 2009-2010   26 / 49
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 2009-2010   26 / 49
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 2009-2010   26 / 49
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 2009-2010   26 / 49
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 2009-2010   27 / 49
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 2009-2010   27 / 49
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 2009-2010   27 / 49
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 2009-2010   28 / 49
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 2009-2010   29 / 49
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 2009-2010   29 / 49
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 2009-2010   29 / 49
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 2009-2010   29 / 49
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 2009-2010   29 / 49
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 2009-2010   29 / 49
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 2009-2010   30 / 49
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 2009-2010   31 / 49
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 2009-2010   32 / 49
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 2009-2010   32 / 49
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 2009-2010   32 / 49
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 2009-2010   32 / 49
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 2009-2010   33 / 49
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 2009-2010   33 / 49
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 2009-2010   33 / 49
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 2009-2010   33 / 49
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 2009-2010   33 / 49
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 2009-2010   33 / 49
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 2009-2010   33 / 49
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 2009-2010   33 / 49
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 2009-2010   34 / 49
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 2009-2010   34 / 49
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 2009-2010   35 / 49
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 2009-2010   35 / 49
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 2009-2010   35 / 49
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 2009-2010   35 / 49
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 2009-2010   35 / 49
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 2009-2010   35 / 49
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 2009-2010   36 / 49
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 2009-2010   36 / 49
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 2009-2010   36 / 49
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 2009-2010   36 / 49
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 2009-2010   36 / 49
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 2009-2010   36 / 49
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 2009-2010   37 / 49
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 2009-2010   37 / 49
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 2009-2010   37 / 49
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 2009-2010   37 / 49
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 2009-2010   37 / 49
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 2009-2010   37 / 49
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 2009-2010   38 / 49
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 2009-2010   38 / 49
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 2009-2010   38 / 49
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 2009-2010   38 / 49
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 2009-2010   38 / 49
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 2009-2010   39 / 49
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 2009-2010   39 / 49
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 2009-2010   39 / 49
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 2009-2010   40 / 49
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 2009-2010   40 / 49
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 2009-2010   40 / 49
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 2009-2010   41 / 49
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 2009-2010   41 / 49
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 2009-2010   41 / 49
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 2009-2010   41 / 49
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 2009-2010   41 / 49
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 2009-2010   41 / 49
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 2009-2010   41 / 49
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 2009-2010   41 / 49
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 2009-2010   41 / 49
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 2009-2010   41 / 49
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 2009-2010   42 / 49
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)
              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 2009-2010     43 / 49
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)
              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 2009-2010     43 / 49
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)
              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 2009-2010     43 / 49
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)
              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 2009-2010     43 / 49
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)
              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 2009-2010     43 / 49
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)
              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 2009-2010     43 / 49
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)
              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 2009-2010     43 / 49
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)
              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 2009-2010     43 / 49
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)
              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 2009-2010     43 / 49
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)
              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 2009-2010     43 / 49
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)
              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 2009-2010     43 / 49
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__(self, arg=0.0):                         def __new__(cls, arg=0.0):
     return float.__init__(self,                          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 2009-2010   44 / 49
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__(self, arg=0.0):                         def __new__(cls, arg=0.0):
     return float.__init__(self,                          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 2009-2010   44 / 49
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__(self, arg=0.0):                         def __new__(cls, arg=0.0):
     return float.__init__(self,                          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 2009-2010   44 / 49
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__(self, arg=0.0):                         def __new__(cls, arg=0.0):
     return float.__init__(self,                          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 2009-2010   44 / 49
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__(self, arg=0.0):                         def __new__(cls, arg=0.0):
     return float.__init__(self,                          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 2009-2010   44 / 49
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__(self, arg=0.0):                         def __new__(cls, arg=0.0):
     return float.__init__(self,                          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 2009-2010   44 / 49
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__(self, arg=0.0):                         def __new__(cls, arg=0.0):
     return float.__init__(self,                          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 2009-2010   44 / 49
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 2009-2010   45 / 49
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 2009-2010   45 / 49
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 2009-2010   45 / 49
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 2009-2010   45 / 49
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 2009-2010   45 / 49
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 2009-2010   45 / 49
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 2009-2010   46 / 49
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 2009-2010   46 / 49
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 2009-2010   46 / 49
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 2009-2010   47 / 49
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 2009-2010   48 / 49
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 2009-2010   49 / 49

More Related Content

What's hot (16)

Ontology Integration and Interoperability (OntoIOp) – Part 1: The Distributed...
Ontology Integration and Interoperability (OntoIOp) – Part 1: The Distributed...Ontology Integration and Interoperability (OntoIOp) – Part 1: The Distributed...
Ontology Integration and Interoperability (OntoIOp) – Part 1: The Distributed...
Christoph Lange
 
Object Oriented Approach Within Siebel Boundaries
Object Oriented Approach Within Siebel BoundariesObject Oriented Approach Within Siebel Boundaries
Object Oriented Approach Within Siebel Boundaries
Roman Agaev
 
10.1.1.35.8376
10.1.1.35.837610.1.1.35.8376
10.1.1.35.8376
Mahmoud Abdullah
 
Propelling Standards-based Sharing and Reuse in Instructional Modeling Commun...
Propelling Standards-based Sharing and Reuse in Instructional Modeling Commun...Propelling Standards-based Sharing and Reuse in Instructional Modeling Commun...
Propelling Standards-based Sharing and Reuse in Instructional Modeling Commun...
Michael Derntl
 
Pal gov.tutorial4.session1 1.needforsharedsemantics
Pal gov.tutorial4.session1 1.needforsharedsemanticsPal gov.tutorial4.session1 1.needforsharedsemantics
Pal gov.tutorial4.session1 1.needforsharedsemantics
Mustafa Jarrar
 
Object oriented programming
Object oriented programmingObject oriented programming
Object oriented programming
Sandeep Kumar Singh
 
Natural language processing using python
Natural language processing using pythonNatural language processing using python
Natural language processing using python
Prakash Anand
 
Icsme16.ppt
Icsme16.pptIcsme16.ppt
Icsme16.ppt
Yann-Gaël Guéhéneuc
 
IRJET- Survey on Generating Suggestions for Erroneous Part in a Sentence
IRJET- Survey on Generating Suggestions for Erroneous Part in a SentenceIRJET- Survey on Generating Suggestions for Erroneous Part in a Sentence
IRJET- Survey on Generating Suggestions for Erroneous Part in a Sentence
IRJET Journal
 
Extractive Summarization with Very Deep Pretrained Language Model
Extractive Summarization with Very Deep Pretrained Language ModelExtractive Summarization with Very Deep Pretrained Language Model
Extractive Summarization with Very Deep Pretrained Language Model
gerogepatton
 
Pal gov.tutorial4.outline
Pal gov.tutorial4.outlinePal gov.tutorial4.outline
Pal gov.tutorial4.outline
Mustafa Jarrar
 
Modeling of Speech Synthesis of Standard Arabic Using an Expert System
Modeling of Speech Synthesis of Standard Arabic Using an Expert SystemModeling of Speech Synthesis of Standard Arabic Using an Expert System
Modeling of Speech Synthesis of Standard Arabic Using an Expert System
csandit
 
Csci360 20 (1)
Csci360 20 (1)Csci360 20 (1)
Csci360 20 (1)
manish katara
 
Csci360 20
Csci360 20Csci360 20
Csci360 20
neetukalra
 
DETERMINING CUSTOMER SATISFACTION IN-ECOMMERCE
DETERMINING CUSTOMER SATISFACTION IN-ECOMMERCEDETERMINING CUSTOMER SATISFACTION IN-ECOMMERCE
DETERMINING CUSTOMER SATISFACTION IN-ECOMMERCE
AbdurrahimDerric
 
Lecture 12
Lecture 12Lecture 12
Lecture 12
talha ijaz
 
Ontology Integration and Interoperability (OntoIOp) – Part 1: The Distributed...
Ontology Integration and Interoperability (OntoIOp) – Part 1: The Distributed...Ontology Integration and Interoperability (OntoIOp) – Part 1: The Distributed...
Ontology Integration and Interoperability (OntoIOp) – Part 1: The Distributed...
Christoph Lange
 
Object Oriented Approach Within Siebel Boundaries
Object Oriented Approach Within Siebel BoundariesObject Oriented Approach Within Siebel Boundaries
Object Oriented Approach Within Siebel Boundaries
Roman Agaev
 
Propelling Standards-based Sharing and Reuse in Instructional Modeling Commun...
Propelling Standards-based Sharing and Reuse in Instructional Modeling Commun...Propelling Standards-based Sharing and Reuse in Instructional Modeling Commun...
Propelling Standards-based Sharing and Reuse in Instructional Modeling Commun...
Michael Derntl
 
Pal gov.tutorial4.session1 1.needforsharedsemantics
Pal gov.tutorial4.session1 1.needforsharedsemanticsPal gov.tutorial4.session1 1.needforsharedsemantics
Pal gov.tutorial4.session1 1.needforsharedsemantics
Mustafa Jarrar
 
Natural language processing using python
Natural language processing using pythonNatural language processing using python
Natural language processing using python
Prakash Anand
 
IRJET- Survey on Generating Suggestions for Erroneous Part in a Sentence
IRJET- Survey on Generating Suggestions for Erroneous Part in a SentenceIRJET- Survey on Generating Suggestions for Erroneous Part in a Sentence
IRJET- Survey on Generating Suggestions for Erroneous Part in a Sentence
IRJET Journal
 
Extractive Summarization with Very Deep Pretrained Language Model
Extractive Summarization with Very Deep Pretrained Language ModelExtractive Summarization with Very Deep Pretrained Language Model
Extractive Summarization with Very Deep Pretrained Language Model
gerogepatton
 
Pal gov.tutorial4.outline
Pal gov.tutorial4.outlinePal gov.tutorial4.outline
Pal gov.tutorial4.outline
Mustafa Jarrar
 
Modeling of Speech Synthesis of Standard Arabic Using an Expert System
Modeling of Speech Synthesis of Standard Arabic Using an Expert SystemModeling of Speech Synthesis of Standard Arabic Using an Expert System
Modeling of Speech Synthesis of Standard Arabic Using an Expert System
csandit
 
DETERMINING CUSTOMER SATISFACTION IN-ECOMMERCE
DETERMINING CUSTOMER SATISFACTION IN-ECOMMERCEDETERMINING CUSTOMER SATISFACTION IN-ECOMMERCE
DETERMINING CUSTOMER SATISFACTION IN-ECOMMERCE
AbdurrahimDerric
 

Viewers also liked (8)

Powerpoint de maría bayo martínez hcyt
Powerpoint de maría bayo martínez hcytPowerpoint de maría bayo martínez hcyt
Powerpoint de maría bayo martínez hcyt
María Bayo Martínez
 
MacPherson Group Presentation
MacPherson Group PresentationMacPherson Group Presentation
MacPherson Group Presentation
angelodanielrossi
 
CQ Personnel Presentation
CQ Personnel PresentationCQ Personnel Presentation
CQ Personnel Presentation
angelodanielrossi
 
Hostel lyf new
Hostel lyf newHostel lyf new
Hostel lyf new
Anchal Sharma
 
CQ/VMS Global Presentation
CQ/VMS Global PresentationCQ/VMS Global Presentation
CQ/VMS Global Presentation
angelodanielrossi
 
Back Bay Staffing Group
Back Bay Staffing GroupBack Bay Staffing Group
Back Bay Staffing Group
angelodanielrossi
 
Sistema de Salud en el Peru
Sistema de Salud en el Peru  Sistema de Salud en el Peru
Sistema de Salud en el Peru
UNMSM
 
Linear programming
Linear programmingLinear programming
Linear programming
Ishu Priya Agarwal
 
Powerpoint de maría bayo martínez hcyt
Powerpoint de maría bayo martínez hcytPowerpoint de maría bayo martínez hcyt
Powerpoint de maría bayo martínez hcyt
María Bayo Martínez
 
MacPherson Group Presentation
MacPherson Group PresentationMacPherson Group Presentation
MacPherson Group Presentation
angelodanielrossi
 
Sistema de Salud en el Peru
Sistema de Salud en el Peru  Sistema de Salud en el Peru
Sistema de Salud en el Peru
UNMSM
 
Ad

Similar to Object Oriented Programming in Python (20)

Object-oriented Programming in Python
Object-oriented Programming in PythonObject-oriented Programming in Python
Object-oriented Programming in Python
Juan-Manuel Gimeno
 
Unit-V.pptx
Unit-V.pptxUnit-V.pptx
Unit-V.pptx
AtharvaPimple1
 
Software Programming with Python II.pptx
Software Programming with Python II.pptxSoftware Programming with Python II.pptx
Software Programming with Python II.pptx
GevitaChinnaiah
 
bhaskars.pptx
bhaskars.pptxbhaskars.pptx
bhaskars.pptx
NaveenShankar34
 
Object oriented programming in python
Object oriented programming in pythonObject oriented programming in python
Object oriented programming in python
nitamhaske
 
Ways To Become A Good Python Developer
Ways To Become A Good Python DeveloperWays To Become A Good Python Developer
Ways To Become A Good Python Developer
CodeMonk
 
James Jesus Bermas on Crash Course on Python
James Jesus Bermas on Crash Course on PythonJames Jesus Bermas on Crash Course on Python
James Jesus Bermas on Crash Course on Python
CP-Union
 
software construction and development week 3 Python lists, tuples, dictionari...
software construction and development week 3 Python lists, tuples, dictionari...software construction and development week 3 Python lists, tuples, dictionari...
software construction and development week 3 Python lists, tuples, dictionari...
MuhammadBilalAjmal2
 
Comparison of OOP with Procedural and Functional Programming
Comparison of OOP with Procedural and Functional ProgrammingComparison of OOP with Procedural and Functional Programming
Comparison of OOP with Procedural and Functional Programming
infoguestbloging
 
Different paradigms for problem solving.pptx
Different paradigms for problem solving.pptxDifferent paradigms for problem solving.pptx
Different paradigms for problem solving.pptx
iitjeesooraj
 
python1 object oriented programming.pptx
python1 object oriented programming.pptxpython1 object oriented programming.pptx
python1 object oriented programming.pptx
PravinBhargav1
 
oogshsvshsbhshhshvsvshsvsvhshshjshshhsvgps.pptx
oogshsvshsbhshhshvsvshsvsvhshshjshshhsvgps.pptxoogshsvshsbhshhshvsvshsvsvhshshjshshhsvgps.pptx
oogshsvshsbhshhshvsvshsvsvhshshjshshhsvgps.pptx
BhojarajTheking
 
Programming paradigm
Programming paradigmProgramming paradigm
Programming paradigm
busyking03
 
Overview of python 2019
Overview of python 2019Overview of python 2019
Overview of python 2019
Samir Mohanty
 
Python Introduction object oriented Progamming
Python Introduction object oriented ProgammingPython Introduction object oriented Progamming
Python Introduction object oriented Progamming
PradeepT42
 
Exploratory Analytics in Python provided by EY.pdf
Exploratory Analytics in Python provided by EY.pdfExploratory Analytics in Python provided by EY.pdf
Exploratory Analytics in Python provided by EY.pdf
totondak
 
python-an-introduction
python-an-introductionpython-an-introduction
python-an-introduction
Shrinivasan T
 
Object Oriented Programming in Python.pptx
Object Oriented Programming in Python.pptxObject Oriented Programming in Python.pptx
Object Oriented Programming in Python.pptx
grpvasundhara1993
 
Object Oriented Programming Part 2 of Unit 1
Object Oriented Programming Part 2 of Unit 1Object Oriented Programming Part 2 of Unit 1
Object Oriented Programming Part 2 of Unit 1
VigneshkumarPonnusam1
 
bhaskars.pptx
bhaskars.pptxbhaskars.pptx
bhaskars.pptx
Naveen316549
 
Object-oriented Programming in Python
Object-oriented Programming in PythonObject-oriented Programming in Python
Object-oriented Programming in Python
Juan-Manuel Gimeno
 
Software Programming with Python II.pptx
Software Programming with Python II.pptxSoftware Programming with Python II.pptx
Software Programming with Python II.pptx
GevitaChinnaiah
 
Object oriented programming in python
Object oriented programming in pythonObject oriented programming in python
Object oriented programming in python
nitamhaske
 
Ways To Become A Good Python Developer
Ways To Become A Good Python DeveloperWays To Become A Good Python Developer
Ways To Become A Good Python Developer
CodeMonk
 
James Jesus Bermas on Crash Course on Python
James Jesus Bermas on Crash Course on PythonJames Jesus Bermas on Crash Course on Python
James Jesus Bermas on Crash Course on Python
CP-Union
 
software construction and development week 3 Python lists, tuples, dictionari...
software construction and development week 3 Python lists, tuples, dictionari...software construction and development week 3 Python lists, tuples, dictionari...
software construction and development week 3 Python lists, tuples, dictionari...
MuhammadBilalAjmal2
 
Comparison of OOP with Procedural and Functional Programming
Comparison of OOP with Procedural and Functional ProgrammingComparison of OOP with Procedural and Functional Programming
Comparison of OOP with Procedural and Functional Programming
infoguestbloging
 
Different paradigms for problem solving.pptx
Different paradigms for problem solving.pptxDifferent paradigms for problem solving.pptx
Different paradigms for problem solving.pptx
iitjeesooraj
 
python1 object oriented programming.pptx
python1 object oriented programming.pptxpython1 object oriented programming.pptx
python1 object oriented programming.pptx
PravinBhargav1
 
oogshsvshsbhshhshvsvshsvsvhshshjshshhsvgps.pptx
oogshsvshsbhshhshvsvshsvsvhshshjshshhsvgps.pptxoogshsvshsbhshhshvsvshsvsvhshshjshshhsvgps.pptx
oogshsvshsbhshhshvsvshsvsvhshshjshshhsvgps.pptx
BhojarajTheking
 
Programming paradigm
Programming paradigmProgramming paradigm
Programming paradigm
busyking03
 
Overview of python 2019
Overview of python 2019Overview of python 2019
Overview of python 2019
Samir Mohanty
 
Python Introduction object oriented Progamming
Python Introduction object oriented ProgammingPython Introduction object oriented Progamming
Python Introduction object oriented Progamming
PradeepT42
 
Exploratory Analytics in Python provided by EY.pdf
Exploratory Analytics in Python provided by EY.pdfExploratory Analytics in Python provided by EY.pdf
Exploratory Analytics in Python provided by EY.pdf
totondak
 
python-an-introduction
python-an-introductionpython-an-introduction
python-an-introduction
Shrinivasan T
 
Object Oriented Programming in Python.pptx
Object Oriented Programming in Python.pptxObject Oriented Programming in Python.pptx
Object Oriented Programming in Python.pptx
grpvasundhara1993
 
Object Oriented Programming Part 2 of Unit 1
Object Oriented Programming Part 2 of Unit 1Object Oriented Programming Part 2 of Unit 1
Object Oriented Programming Part 2 of Unit 1
VigneshkumarPonnusam1
 
Ad

Recently uploaded (20)

Creating an Accessible Future-How AI-powered Accessibility Testing is Shaping...
Creating an Accessible Future-How AI-powered Accessibility Testing is Shaping...Creating an Accessible Future-How AI-powered Accessibility Testing is Shaping...
Creating an Accessible Future-How AI-powered Accessibility Testing is Shaping...
Impelsys Inc.
 
Jeremy Millul - A Talented Software Developer
Jeremy Millul - A Talented Software DeveloperJeremy Millul - A Talented Software Developer
Jeremy Millul - A Talented Software Developer
Jeremy Millul
 
MCP vs A2A vs ACP: Choosing the Right Protocol | Bluebash
MCP vs A2A vs ACP: Choosing the Right Protocol | BluebashMCP vs A2A vs ACP: Choosing the Right Protocol | Bluebash
MCP vs A2A vs ACP: Choosing the Right Protocol | Bluebash
Bluebash
 
ISOIEC 42005 Revolutionalises AI Impact Assessment.pptx
ISOIEC 42005 Revolutionalises AI Impact Assessment.pptxISOIEC 42005 Revolutionalises AI Impact Assessment.pptx
ISOIEC 42005 Revolutionalises AI Impact Assessment.pptx
AyilurRamnath1
 
If You Use Databricks, You Definitely Need FME
If You Use Databricks, You Definitely Need FMEIf You Use Databricks, You Definitely Need FME
If You Use Databricks, You Definitely Need FME
Safe Software
 
Introduction to Internet of things .ppt.
Introduction to Internet of things .ppt.Introduction to Internet of things .ppt.
Introduction to Internet of things .ppt.
hok12341073
 
cnc-drilling-dowel-inserting-machine-drillteq-d-510-english.pdf
cnc-drilling-dowel-inserting-machine-drillteq-d-510-english.pdfcnc-drilling-dowel-inserting-machine-drillteq-d-510-english.pdf
cnc-drilling-dowel-inserting-machine-drillteq-d-510-english.pdf
AmirStern2
 
“How Qualcomm Is Powering AI-driven Multimedia at the Edge,” a Presentation f...
“How Qualcomm Is Powering AI-driven Multimedia at the Edge,” a Presentation f...“How Qualcomm Is Powering AI-driven Multimedia at the Edge,” a Presentation f...
“How Qualcomm Is Powering AI-driven Multimedia at the Edge,” a Presentation f...
Edge AI and Vision Alliance
 
How to Detect Outliers in IBM SPSS Statistics.pptx
How to Detect Outliers in IBM SPSS Statistics.pptxHow to Detect Outliers in IBM SPSS Statistics.pptx
How to Detect Outliers in IBM SPSS Statistics.pptx
Version 1 Analytics
 
Bridging the divide: A conversation on tariffs today in the book industry - T...
Bridging the divide: A conversation on tariffs today in the book industry - T...Bridging the divide: A conversation on tariffs today in the book industry - T...
Bridging the divide: A conversation on tariffs today in the book industry - T...
BookNet Canada
 
AI Agents in Logistics and Supply Chain Applications Benefits and Implementation
AI Agents in Logistics and Supply Chain Applications Benefits and ImplementationAI Agents in Logistics and Supply Chain Applications Benefits and Implementation
AI Agents in Logistics and Supply Chain Applications Benefits and Implementation
Christine Shepherd
 
What is Oracle EPM A Guide to Oracle EPM Cloud Everything You Need to Know
What is Oracle EPM A Guide to Oracle EPM Cloud Everything You Need to KnowWhat is Oracle EPM A Guide to Oracle EPM Cloud Everything You Need to Know
What is Oracle EPM A Guide to Oracle EPM Cloud Everything You Need to Know
SMACT Works
 
How Advanced Environmental Detection Is Revolutionizing Oil & Gas Safety.pdf
How Advanced Environmental Detection Is Revolutionizing Oil & Gas Safety.pdfHow Advanced Environmental Detection Is Revolutionizing Oil & Gas Safety.pdf
How Advanced Environmental Detection Is Revolutionizing Oil & Gas Safety.pdf
Rejig Digital
 
Down the Rabbit Hole – Solving 5 Training Roadblocks
Down the Rabbit Hole – Solving 5 Training RoadblocksDown the Rabbit Hole – Solving 5 Training Roadblocks
Down the Rabbit Hole – Solving 5 Training Roadblocks
Rustici Software
 
Agentic AI: Beyond the Buzz- LangGraph Studio V2
Agentic AI: Beyond the Buzz- LangGraph Studio V2Agentic AI: Beyond the Buzz- LangGraph Studio V2
Agentic AI: Beyond the Buzz- LangGraph Studio V2
Shashikant Jagtap
 
National Fuels Treatments Initiative: Building a Seamless Map of Hazardous Fu...
National Fuels Treatments Initiative: Building a Seamless Map of Hazardous Fu...National Fuels Treatments Initiative: Building a Seamless Map of Hazardous Fu...
National Fuels Treatments Initiative: Building a Seamless Map of Hazardous Fu...
Safe Software
 
Oracle Cloud Infrastructure AI Foundations
Oracle Cloud Infrastructure AI FoundationsOracle Cloud Infrastructure AI Foundations
Oracle Cloud Infrastructure AI Foundations
VICTOR MAESTRE RAMIREZ
 
GIS and FME: The Foundation to Improve the Locate Process of Utilities
GIS and FME: The Foundation to Improve the Locate Process of UtilitiesGIS and FME: The Foundation to Improve the Locate Process of Utilities
GIS and FME: The Foundation to Improve the Locate Process of Utilities
Safe Software
 
Developing Schemas with FME and Excel - Peak of Data & AI 2025
Developing Schemas with FME and Excel - Peak of Data & AI 2025Developing Schemas with FME and Excel - Peak of Data & AI 2025
Developing Schemas with FME and Excel - Peak of Data & AI 2025
Safe Software
 
Data Virtualization: Bringing the Power of FME to Any Application
Data Virtualization: Bringing the Power of FME to Any ApplicationData Virtualization: Bringing the Power of FME to Any Application
Data Virtualization: Bringing the Power of FME to Any Application
Safe Software
 
Creating an Accessible Future-How AI-powered Accessibility Testing is Shaping...
Creating an Accessible Future-How AI-powered Accessibility Testing is Shaping...Creating an Accessible Future-How AI-powered Accessibility Testing is Shaping...
Creating an Accessible Future-How AI-powered Accessibility Testing is Shaping...
Impelsys Inc.
 
Jeremy Millul - A Talented Software Developer
Jeremy Millul - A Talented Software DeveloperJeremy Millul - A Talented Software Developer
Jeremy Millul - A Talented Software Developer
Jeremy Millul
 
MCP vs A2A vs ACP: Choosing the Right Protocol | Bluebash
MCP vs A2A vs ACP: Choosing the Right Protocol | BluebashMCP vs A2A vs ACP: Choosing the Right Protocol | Bluebash
MCP vs A2A vs ACP: Choosing the Right Protocol | Bluebash
Bluebash
 
ISOIEC 42005 Revolutionalises AI Impact Assessment.pptx
ISOIEC 42005 Revolutionalises AI Impact Assessment.pptxISOIEC 42005 Revolutionalises AI Impact Assessment.pptx
ISOIEC 42005 Revolutionalises AI Impact Assessment.pptx
AyilurRamnath1
 
If You Use Databricks, You Definitely Need FME
If You Use Databricks, You Definitely Need FMEIf You Use Databricks, You Definitely Need FME
If You Use Databricks, You Definitely Need FME
Safe Software
 
Introduction to Internet of things .ppt.
Introduction to Internet of things .ppt.Introduction to Internet of things .ppt.
Introduction to Internet of things .ppt.
hok12341073
 
cnc-drilling-dowel-inserting-machine-drillteq-d-510-english.pdf
cnc-drilling-dowel-inserting-machine-drillteq-d-510-english.pdfcnc-drilling-dowel-inserting-machine-drillteq-d-510-english.pdf
cnc-drilling-dowel-inserting-machine-drillteq-d-510-english.pdf
AmirStern2
 
“How Qualcomm Is Powering AI-driven Multimedia at the Edge,” a Presentation f...
“How Qualcomm Is Powering AI-driven Multimedia at the Edge,” a Presentation f...“How Qualcomm Is Powering AI-driven Multimedia at the Edge,” a Presentation f...
“How Qualcomm Is Powering AI-driven Multimedia at the Edge,” a Presentation f...
Edge AI and Vision Alliance
 
How to Detect Outliers in IBM SPSS Statistics.pptx
How to Detect Outliers in IBM SPSS Statistics.pptxHow to Detect Outliers in IBM SPSS Statistics.pptx
How to Detect Outliers in IBM SPSS Statistics.pptx
Version 1 Analytics
 
Bridging the divide: A conversation on tariffs today in the book industry - T...
Bridging the divide: A conversation on tariffs today in the book industry - T...Bridging the divide: A conversation on tariffs today in the book industry - T...
Bridging the divide: A conversation on tariffs today in the book industry - T...
BookNet Canada
 
AI Agents in Logistics and Supply Chain Applications Benefits and Implementation
AI Agents in Logistics and Supply Chain Applications Benefits and ImplementationAI Agents in Logistics and Supply Chain Applications Benefits and Implementation
AI Agents in Logistics and Supply Chain Applications Benefits and Implementation
Christine Shepherd
 
What is Oracle EPM A Guide to Oracle EPM Cloud Everything You Need to Know
What is Oracle EPM A Guide to Oracle EPM Cloud Everything You Need to KnowWhat is Oracle EPM A Guide to Oracle EPM Cloud Everything You Need to Know
What is Oracle EPM A Guide to Oracle EPM Cloud Everything You Need to Know
SMACT Works
 
How Advanced Environmental Detection Is Revolutionizing Oil & Gas Safety.pdf
How Advanced Environmental Detection Is Revolutionizing Oil & Gas Safety.pdfHow Advanced Environmental Detection Is Revolutionizing Oil & Gas Safety.pdf
How Advanced Environmental Detection Is Revolutionizing Oil & Gas Safety.pdf
Rejig Digital
 
Down the Rabbit Hole – Solving 5 Training Roadblocks
Down the Rabbit Hole – Solving 5 Training RoadblocksDown the Rabbit Hole – Solving 5 Training Roadblocks
Down the Rabbit Hole – Solving 5 Training Roadblocks
Rustici Software
 
Agentic AI: Beyond the Buzz- LangGraph Studio V2
Agentic AI: Beyond the Buzz- LangGraph Studio V2Agentic AI: Beyond the Buzz- LangGraph Studio V2
Agentic AI: Beyond the Buzz- LangGraph Studio V2
Shashikant Jagtap
 
National Fuels Treatments Initiative: Building a Seamless Map of Hazardous Fu...
National Fuels Treatments Initiative: Building a Seamless Map of Hazardous Fu...National Fuels Treatments Initiative: Building a Seamless Map of Hazardous Fu...
National Fuels Treatments Initiative: Building a Seamless Map of Hazardous Fu...
Safe Software
 
Oracle Cloud Infrastructure AI Foundations
Oracle Cloud Infrastructure AI FoundationsOracle Cloud Infrastructure AI Foundations
Oracle Cloud Infrastructure AI Foundations
VICTOR MAESTRE RAMIREZ
 
GIS and FME: The Foundation to Improve the Locate Process of Utilities
GIS and FME: The Foundation to Improve the Locate Process of UtilitiesGIS and FME: The Foundation to Improve the Locate Process of Utilities
GIS and FME: The Foundation to Improve the Locate Process of Utilities
Safe Software
 
Developing Schemas with FME and Excel - Peak of Data & AI 2025
Developing Schemas with FME and Excel - Peak of Data & AI 2025Developing Schemas with FME and Excel - Peak of Data & AI 2025
Developing Schemas with FME and Excel - Peak of Data & AI 2025
Safe Software
 
Data Virtualization: Bringing the Power of FME to Any Application
Data Virtualization: Bringing the Power of FME to Any ApplicationData Virtualization: Bringing the Power of FME to Any Application
Data Virtualization: Bringing the Power of FME to Any Application
Safe Software
 

Object Oriented Programming in Python

  • 1. Object Oriented Programming in Python Juan Manuel Gimeno Illa [email protected] Curs 2009-2010 J.M.Gimeno ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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) 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 ([email protected]) OOP in Python Curs 2009-2010 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) 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 ([email protected]) OOP in Python Curs 2009-2010 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) 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 ([email protected]) OOP in Python Curs 2009-2010 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) 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 ([email protected]) OOP in Python Curs 2009-2010 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) 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 ([email protected]) OOP in Python Curs 2009-2010 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) 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 ([email protected]) OOP in Python Curs 2009-2010 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) 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 ([email protected]) OOP in Python Curs 2009-2010 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) 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 ([email protected]) OOP in Python Curs 2009-2010 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) 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 ([email protected]) OOP in Python Curs 2009-2010 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) 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 ([email protected]) OOP in Python Curs 2009-2010 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) 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 ([email protected]) OOP in Python Curs 2009-2010 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__(self, arg=0.0): def __new__(cls, arg=0.0): return float.__init__(self, 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 ([email protected]) OOP in Python Curs 2009-2010 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__(self, arg=0.0): def __new__(cls, arg=0.0): return float.__init__(self, 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 ([email protected]) OOP in Python Curs 2009-2010 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__(self, arg=0.0): def __new__(cls, arg=0.0): return float.__init__(self, 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 ([email protected]) OOP in Python Curs 2009-2010 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__(self, arg=0.0): def __new__(cls, arg=0.0): return float.__init__(self, 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 ([email protected]) OOP in Python Curs 2009-2010 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__(self, arg=0.0): def __new__(cls, arg=0.0): return float.__init__(self, 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 ([email protected]) OOP in Python Curs 2009-2010 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__(self, arg=0.0): def __new__(cls, arg=0.0): return float.__init__(self, 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 ([email protected]) OOP in Python Curs 2009-2010 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__(self, arg=0.0): def __new__(cls, arg=0.0): return float.__init__(self, 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 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 ([email protected]) OOP in Python Curs 2009-2010 49 / 49