f



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

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/
0
6/20/2006 4:36:17 PM
comp.lang.python 77058 articles. 6 followers. Post Follow

5 Replies
1165 Views

Similar Articles

[PageSpeed] 14

Le Mardi 20 Juin 2006 18:36, Barry Kelly a =E9crit=A0:
> 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):
> =A0 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 do=
c=20
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'



=2D-=20
_____________

Maric Michaud
_____________

Aristote - www.aristote.info
3 place des tapis
69004 Lyon
Tel: +33 426 880 097
0
maric (225)
6/20/2006 5:26:08 PM
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.daniels@acm.org
0
scott.daniels (1683)
6/20/2006 7:18:19 PM
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

0
6/20/2006 8:47:56 PM
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__
0
6/20/2006 11:01:31 PM
Barry Kelly <barry.j.kelly@gmail.com> 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/
0
6/20/2006 11:17:49 PM
Reply: