__getattribute__ doesn't work on 'type' type for '__class__'

Discussion in 'Python' started by Barry Kelly, Jun 20, 2006.

  1. Barry Kelly

    Barry Kelly Guest

    I'm running this version of Python:

    Python 2.4.3 (#1, May 18 2006, 07:40:45)
    [GCC 3.3.3 (cygwin special)] on cygwin

    I read in the documentation that these two expressions are
    interchangeable:

    x.__getattribute__('name') <==> x.name

    From "pydoc __getattribute__":

    ---8<---
    Help on method-wrapper object:

    __getattribute__ = class method-wrapper(object)
    | Methods defined here:
    |
    | __call__(...)
    | x.__call__(...) <==> x(...)
    |
    | __getattribute__(...)
    | x.__getattribute__('name') <==> x.name
    --->8---

    Yet when I try this with the 'type' type, it doesn't work:

    ---8<---
    >>> x.__class__.__class__

    <type 'type'>
    >>> x.__class__.__getattribute__('__class__')

    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    TypeError: descriptor '__getattribute__' requires a 'int' object but
    received a 'str'
    --->8---

    Why is this?

    -- Barry

    --
    http://barrkel.blogspot.com/
     
    Barry Kelly, Jun 20, 2006
    #1
    1. Advertising

  2. Le Mardi 20 Juin 2006 18:36, Barry Kelly a écrit :
    > Yet when I try this with the 'type' type, it doesn't work:
    >
    > ---8<---
    >
    > >>> x.__class__.__class__

    >
    > <type 'type'>
    >
    > >>> x.__class__.__getattribute__('__class__')

    >

    you're looking for getattr :

    In [11]: getattr(object, '__class__')
    Out[12]: <type 'type'>

    In [13]: getattr(str, 'translate')
    Out[13]: <method 'translate' of 'str' objects>

    > Traceback (most recent call last):
    >   File "<stdin>", line 1, in ?
    > TypeError: descriptor '__getattribute__' requires a 'int' object but
    > received a 'str'
    > --->8---
    >
    > Why is this?


    __getattribute__ is the descriptor interface, that means... humm see the doc
    i'm not enough skilled in english to explain in few words...
    but in python :

    In [27]: 'aaa'.replace('a', 'z')
    Out[27]: 'zzz'

    is exactly the same as :

    In [25]: str.__getattribute__('aaa', 'replace')('a', 'z')
    Out[25]: 'zzz'

    or even :

    In [26]: object.__getattribute__('aaa', 'replace')('a', 'z')
    Out[26]: 'zzz'



    --
    _____________

    Maric Michaud
    _____________

    Aristote - www.aristote.info
    3 place des tapis
    69004 Lyon
    Tel: +33 426 880 097
     
    Maric Michaud, Jun 20, 2006
    #2
    1. Advertising

  3. Barry Kelly wrote:
    > I read in the documentation that these two expressions are
    > interchangeable:
    > x.__getattribute__('name') <==> x.name


    I think you'll find:
    getattr(x, 'name') <==> x.name

    is what is equivalent. You can define a '__getattribute__'
    method which will get used, but I doublbt thre is a promise for
    an exposed name '__getattribute__'.

    --
    --Scott David Daniels
     
    Scott David Daniels, Jun 20, 2006
    #3
  4. Barry Kelly wrote:
    [snipped]
    > Yet when I try this with the 'type' type, it doesn't work:
    >
    > ---8<---
    > >>> x.__class__.__class__

    > <type 'type'>
    > >>> x.__class__.__getattribute__('__class__')

    > Traceback (most recent call last):
    > File "<stdin>", line 1, in ?
    > TypeError: descriptor '__getattribute__' requires a 'int' object but
    > received a 'str'
    > --->8---
    >
    > Why is this?


    The problem is that your class (I would guess that x is an int) and its
    type have a method with the same name. As is normal for attribute
    lookup, the instance's attribute is first looked up in its __dict__.
    Since x.__class__ is a type, this results in __getattribute__
    being an unbound method of that type. What you are doing
    is similar to:

    >>> L = ["spam", "eggs"]
    >>> "".__class__.join(L)

    Traceback (most recent call last):
    ...
    TypeError: descriptor 'join' requires a 'str' object but received a
    'list'

    Which as you can see, fails with the same error message.

    > -- Barry
    >
    > --
    > http://barrkel.blogspot.com/


    Hope this helps,

    Ziga
     
    Ziga Seilnacht, Jun 20, 2006
    #4
  5. Barry Kelly a écrit :
    > I'm running this version of Python:
    >
    > Python 2.4.3 (#1, May 18 2006, 07:40:45)
    > [GCC 3.3.3 (cygwin special)] on cygwin
    >
    > I read in the documentation that these two expressions are
    > interchangeable:
    >
    > x.__getattribute__('name') <==> x.name


    I wouldn't say they are interchangeable. FWIW, __getattribute__ starts
    and ends with two underscores which in Python - and a lot of other
    languages - has a very strong 'language internals, black magic stuff,
    not intented for direct client code use'.

    >
    > Yet when I try this with the 'type' type, it doesn't work:
    >
    > ---8<---
    >
    >>>>x.__class__.__class__

    >
    > <type 'type'>
    >
    >>>>x.__class__.__getattribute__('__class__')


    You're calling __getattribute__ on x.__class__, not on
    x.__class__.__class__. But anyway, __getattribute__ is a descriptor,
    which implies different behaviour when called on a class object. Please
    read the doc on the descriptor protocol. For making long things short,
    instance.__getattribute__('attrname')
    translates to
    klass.__getattribute__(instance, 'attrname')

    > Traceback (most recent call last):
    > File "<stdin>", line 1, in ?
    > TypeError: descriptor '__getattribute__' requires a 'int' object but
    > received a 'str'


    I deduce from this that your 'x' is an int. Since you're calling
    __getattribute__ on the type 'int', you have to pass an int as the first
    parameter, ie:

    >>> x = 1
    >>> x.__class__.__getattribute__(x, '__class__')

    <type 'int'>

    Note BTW that it returns x.__class__, not x.__class__.__class__
     
    Bruno Desthuilliers, Jun 21, 2006
    #5
  6. Barry Kelly

    Barry Kelly Guest

    Barry Kelly <> wrote:

    > From "pydoc __getattribute__":
    >
    > ---8<---
    > Help on method-wrapper object:
    >
    > __getattribute__ = class method-wrapper(object)
    > | Methods defined here:
    > |
    > | __call__(...)
    > | x.__call__(...) <==> x(...)
    > |
    > | __getattribute__(...)
    > | x.__getattribute__('name') <==> x.name
    > --->8---


    Thanks for the answers, folks. I did find getattr() quite quickly from
    Google, but it's clear that the documentation with Python is wrong.

    -- Barry

    --
    http://barrkel.blogspot.com/
     
    Barry Kelly, Jun 21, 2006
    #6
    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. gregory lielens
    Replies:
    6
    Views:
    603
    Gregory Lielens
    Dec 2, 2004
  2. Replies:
    1
    Views:
    412
  3. Amirouche B.
    Replies:
    5
    Views:
    233
    Amirouche B.
    Aug 23, 2011
  4. Ivan Yurchenko
    Replies:
    1
    Views:
    334
    Steven D'Aprano
    Feb 10, 2013
  5. Steven D'Aprano
    Replies:
    10
    Views:
    136
    Gregory Ewing
    Dec 18, 2013
Loading...

Share This Page