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

B

Barry Kelly

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<---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
 
M

Maric Michaud

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<---
you're looking for getattr :

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

In [13]: getattr(str, 'translate')
Out[13]: said:
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
 
S

Scott David Daniels

Barry said:
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__'.
 
Z

Ziga Seilnacht

Barry Kelly wrote:
[snipped]
Yet when I try this with the 'type' type, it doesn't work:

---8<---
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.

Hope this helps,

Ziga
 
B

Bruno Desthuilliers

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<---

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:
<type 'int'>

Note BTW that it returns x.__class__, not x.__class__.__class__
 
B

Barry Kelly

Barry Kelly said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top