Attribute reference design

Discussion in 'Python' started by chamalulu, Jul 1, 2008.

  1. chamalulu

    chamalulu Guest

    Hello.
    I think I'm aware of how attribute access is resolved in python. When
    referencing a class instance attribute which is not defined in the
    scope of the instance, Python looks for a class attribute with the
    same name. (For assignment or deletion this is not the case,
    thankfully.)
    I've been trying to understand why? What is the reason behind, or
    practical purpose of, this design decision? Anyone, please enlighten
    me.

    /Henrik
    chamalulu, Jul 1, 2008
    #1
    1. Advertising

  2. chamalulu schrieb:
    > Hello.
    > I think I'm aware of how attribute access is resolved in python. When
    > referencing a class instance attribute which is not defined in the
    > scope of the instance, Python looks for a class attribute with the
    > same name. (For assignment or deletion this is not the case,
    > thankfully.)
    > I've been trying to understand why? What is the reason behind, or
    > practical purpose of, this design decision? Anyone, please enlighten
    > me.


    How else would you resolve methods which are of course defined on the
    class but invoked through the instance?

    Diez
    Diez B. Roggisch, Jul 1, 2008
    #2
    1. Advertising

  3. chamalulu

    chamalulu Guest

    On Jul 1, 11:24 pm, "Diez B. Roggisch" <> wrote:
    > chamalulu schrieb:
    >
    > > Hello.
    > > I think I'm aware of how attribute access is resolved in python. When
    > > referencing a class instance attribute which is not defined in the
    > > scope of the instance, Python looks for a class attribute with the
    > > same name. (For assignment or deletion this is not the case,
    > > thankfully.)
    > > I've been trying to understand why? What is the reason behind, or
    > > practical purpose of, this design decision? Anyone, please enlighten
    > > me.

    >
    > How else would you resolve methods which are of course defined on the
    > class but invoked through the instance?
    >


    Yes, of course... You're right.
    Didn't think of that.
    Thank you. I'll go stand in the corner. :)

    I think I haven't got this bound/unbound stuff through my head yet. If
    I dir() a class instance I see the methods right there. Are they not
    bound to the class instance at instanciation (and as such be
    attributes of the class instance)?

    /Henrik
    chamalulu, Jul 1, 2008
    #3
  4. chamalulu

    Gary Herron Guest

    chamalulu wrote:
    > On Jul 1, 11:24 pm, "Diez B. Roggisch" <> wrote:
    >
    >> chamalulu schrieb:
    >>
    >>
    >>> Hello.
    >>> I think I'm aware of how attribute access is resolved in python. When
    >>> referencing a class instance attribute which is not defined in the
    >>> scope of the instance, Python looks for a class attribute with the
    >>> same name. (For assignment or deletion this is not the case,
    >>> thankfully.)
    >>> I've been trying to understand why? What is the reason behind, or
    >>> practical purpose of, this design decision? Anyone, please enlighten
    >>> me.
    >>>

    >> How else would you resolve methods which are of course defined on the
    >> class but invoked through the instance?
    >>
    >>

    >
    > Yes, of course... You're right.
    > Didn't think of that.
    > Thank you. I'll go stand in the corner. :)
    >


    No need. Also, you can define a class attribute (C++ might call it a
    static attribute) and access it transparently through an instance.

    class C:
    aClassAttribute = 123
    def __init__(self, ...):
    ...

    c = C()
    .... do something with c.aClassAttribute ...
    > I think I haven't got this bound/unbound stuff through my head yet. If
    > I dir() a class instance I see the methods right there. Are they not
    > bound to the class instance at instanciation (and as such be
    > attributes of the class instance)?
    >
    > /Henrik
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >
    Gary Herron, Jul 2, 2008
    #4
  5. chamalulu

    chamalulu Guest

    On Jul 2, 1:17 am, Gary Herron <> wrote:
    > No need. Also, you can define a class attribute (C++ might call it a
    > static attribute) and access it transparently through an instance.
    >
    > class C:
    > aClassAttribute = 123
    > def __init__(self, ...):
    > ...
    >
    > c = C()
    > ... do something with c.aClassAttribute ...
    >


    Actually, this is why I started too look into the attribute reference
    mechanics to begin with. Coming from mostly C# development I think
    it's weird to be able to refer to class attributes (static members)
    through a class instance (object). But I think I'm getting the
    picture. Function objects lay flat in memory (some heap...). When
    defined inside classes they are wrapped in method objects. When
    refered through classes or class instances they are unbound method
    objects or bound method objects respectively. Am I on the right track?
    I still don't get why these methods show up when I dir() a class
    instance.

    /Henrik
    chamalulu, Jul 2, 2008
    #5
  6. chamalulu

    Gary Herron Guest

    chamalulu wrote:
    > On Jul 2, 1:17 am, Gary Herron <> wrote:
    >
    >> No need. Also, you can define a class attribute (C++ might call it a
    >> static attribute) and access it transparently through an instance.
    >>
    >> class C:
    >> aClassAttribute = 123
    >> def __init__(self, ...):
    >> ...
    >>
    >> c = C()
    >> ... do something with c.aClassAttribute ...
    >>
    >>

    >
    > Actually, this is why I started too look into the attribute reference
    > mechanics to begin with. Coming from mostly C# development I think
    > it's weird to be able to refer to class attributes (static members)
    > through a class instance (object). But I think I'm getting the
    > picture. Function objects lay flat in memory (some heap...).


    Not quite. Not *flat memory* or a heap. Modules are first class
    objects, and functions (and classes and anything else) defined at the
    top level of the module are *attributes* of the module.

    Gary Herron


    > When
    > defined inside classes they are wrapped in method objects. When
    > refered through classes or class instances they are unbound method
    > objects or bound method objects respectively. Am I on the right track?
    > I still don't get why these methods show up when I dir() a class
    > instance.
    >
    > /Henrik
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >
    Gary Herron, Jul 2, 2008
    #6
  7. chamalulu a écrit :
    > On Jul 2, 1:17 am, Gary Herron <> wrote:
    >> No need. Also, you can define a class attribute (C++ might call it a
    >> static attribute) and access it transparently through an instance.
    >>
    >> class C:
    >> aClassAttribute = 123
    >> def __init__(self, ...):
    >> ...
    >>
    >> c = C()
    >> ... do something with c.aClassAttribute ...
    >>

    >
    > Actually, this is why I started too look into the attribute reference
    > mechanics to begin with. Coming from mostly C# development I think
    > it's weird to be able to refer to class attributes (static members)
    > through a class instance (object). But I think I'm getting the
    > picture. Function objects lay flat in memory (some heap...).


    Python's functions are ordinary objects, instance of type 'function'.

    > When
    > defined inside classes they are wrapped in method objects.


    Nope. The wrapping happens at lookup time, thru the descriptor protocol
    (the same thing that gives support for properties).

    > When
    > refered through classes or class instances they are unbound method
    > objects or bound method objects respectively.


    That's what function.__get__() returns, yes. What is stored in the class
    object's __dict__ is the plain function.

    > Am I on the right track?
    > I still don't get why these methods show up when I dir() a class
    > instance.


    """
    Help on built-in function dir in module __builtin__:

    dir(...)
    dir([object]) -> list of strings

    Return an alphabetized list of names comprising (some of) the
    attributes
    of the given object, and of attributes reachable from it:

    No argument: the names in the current scope.
    Module object: the module attributes.
    Type or class object: its attributes, and recursively the
    attributes of
    its bases.
    Otherwise: its attributes, its class's attributes, and recursively the
    attributes of its class's base classes.

    """

    > /Henrik
    Bruno Desthuilliers, Jul 2, 2008
    #7
  8. chamalulu

    chamalulu Guest

    On Jul 2, 10:13 am, Bruno Desthuilliers <bruno.
    > wrote:
    > Nope. The wrapping happens at lookup time, thru the descriptor protocol
    > (the same thing that gives support for properties).


    Aha, I should read up on that.

    > Help on built-in function dir in module __builtin__:


    So, the dir function is a little more helpful than I thaught. I
    checked instance.__dict__ now instead of dir(instance). No methods.
    It's getting clearer. Thank you.

    I think you've provided me with a good reason for class instances to
    delegate attribute references to the class if class instance doesn't
    contain the attribute. Diez, Gary, Bruno; Thanks for your help.

    /Henrik
    chamalulu, Jul 2, 2008
    #8
  9. Le Wednesday 02 July 2008 01:17:21 Gary Herron, vous avez écrit :
    > chamalulu wrote:
    > > On Jul 1, 11:24 pm, "Diez B. Roggisch" <> wrote:
    > >> chamalulu schrieb:
    > >>> Hello.
    > >>> I think I'm aware of how attribute access is resolved in python. When
    > >>> referencing a class instance attribute which is not defined in the
    > >>> scope of the instance, Python looks for a class attribute with the
    > >>> same name. (For assignment or deletion this is not the case,
    > >>> thankfully.)
    > >>> I've been trying to understand why? What is the reason behind, or
    > >>> practical purpose of, this design decision? Anyone, please enlighten
    > >>> me.
    > >>
    > >> How else would you resolve methods which are of course defined on the
    > >> class but invoked through the instance?

    > >
    > > Yes, of course... You're right.
    > > Didn't think of that.
    > > Thank you. I'll go stand in the corner. :)

    >
    > No need. Also, you can define a class attribute (C++ might call it a
    > static attribute) and access it transparently through an instance.
    >
    > class C:
    > aClassAttribute = 123
    > def __init__(self, ...):
    > ...
    >
    > c = C()
    > ... do something with c.aClassAttribute ...
    >


    Be very careful with that, as it looks like C++ or similar other OO languages,
    but python handles it in a strange way if you assign a value to such an
    attribute. It took me a long time to understand what happens here:

    class Foo (object) :
    bar = 0

    foo = Foo()
    print '(1) Foo.bar: %d' % Foo.bar
    print '(1) foo.bar: %d' % foo.bar

    Foo.bar += 1
    print '(2) Foo.bar: %d' % Foo.bar
    print '(2) foo.bar: %d' % foo.bar

    foo.bar += 1
    print '(3) Foo.bar: %d' % Foo.bar
    print '(3) foo.bar: %d' % foo.bar

    here's the output:

    (1) Foo.bar: 0
    (1) foo.bar: 0
    (2) Foo.bar: 1
    (2) foo.bar: 1
    (3) Foo.bar: 1 # hey dude, where is my bar ?
    (3) foo.bar: 2

    In the third case, you might expect foo.bar += 1 to just increment Foo.bar,
    but actually it doesn't. I first thought it was a bug, but it's not. When you
    write foo.bar += 1 (equivalent to foo.bar = foo.bar + 1), python first looks
    for a bar attribute, finds it in the class members, and then creates an
    instance member with the result. Things would be different with a mutable
    type implementing the += operator.

    I discovered this in a middle of a project and it was hard to track all these
    assignments in my code to correct them, so I'd suggest to always access class
    members through the class instead of the instance, unless you have no choice
    or know exactly what you are doing.

    --
    Cédric Lucantis
    Cédric Lucantis, Jul 2, 2008
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Bostonasian
    Replies:
    1
    Views:
    817
    Joris Gillis
    Sep 18, 2005
  2. Replies:
    2
    Views:
    1,076
    Henry S. Thompson
    Mar 6, 2006
  3. Donnal Walter

    class attribute to instance attribute

    Donnal Walter, Jun 30, 2005, in forum: Python
    Replies:
    4
    Views:
    466
    Greg Ewing
    Jul 6, 2005
  4. Russell Warren
    Replies:
    5
    Views:
    470
    Russell Warren
    Jan 17, 2006
  5. anonymous
    Replies:
    1
    Views:
    5,955
Loading...

Share This Page