[Python-Dev] Attribute lookup ambiguity

Pascal Chambon chambon.pascal at wanadoo.fr
Sat Mar 20 13:00:30 CET 2010


Michael Foord a écrit :
>
> On 19/03/2010 18:58, Pascal Chambon wrote:
>> Hello
>>
>> I've already crossed a bunch of articles detailing python's attribute 
>> lookup semantic (__dict__, descriptors, order of base class 
>> traversing...), but I have never seen, so far, an explanation of 
>> WHICH method did waht, exactly.
>>
>> I assumed that getattr(a, b) was the same as a.__getattribute__(b), 
>> and that this __getattribute__ method (or the hidden routine 
>> replacing it when we don't override it in our class) was in charge of 
>> doing the whole job of traversing the object tree, checking 
>> descriptors, binding methods, calling __getattr__ on failure etc.
>>
>> However, the test case below shows that __getattribute__ does NOT 
>> call __getattr__ on failure. So it seems it's an upper levl 
>> machinery, in getattr(), which is in chrge of that last action.
>
> Python 3 has the behavior you are asking for. It would be a backwards 
> incompatible change to do it in Python 2 as __getattribute__ *not* 
> calling __getattr__ is the documented behaviour.
>
> Python 3.2a0 (py3k:78770, Mar 7 2010, 20:32:50)
> [GCC 4.2.1 (Apple Inc. build 5646) (dot 1)] on darwin
> >>> class x:
> ... def __getattribute__(s, name):
> ... print ('__getattribute__', name)
> ... raise AttributeError
> ... def __getattr__(s, name):
> ... print ('__getattr__', name)
> ...
> >>> a = x()
> >>> a.b
> __getattribute__ b
> __getattr__ b
I'm confused there, because the script you gave behaves the same in 
python 2.6. And according to the doc, it's normal, getattr() reacts to 
an AttributeError from __getattribute__, by calling __getattr__ :

"""
Python 2.6.5 documentation

object.__getattribute__(/self/, /name/)

    Called unconditionally to implement attribute accesses for instances
    of the class. If the class also defines __getattr__()
    <http://docs.python.org/reference/datamodel.html#object.__getattr__>,
    the latter will not be called unless __getattribute__()
    <http://docs.python.org/reference/datamodel.html#object.__getattribute__>
    either calls it explicitly or raises an AttributeError
    <http://docs.python.org/library/exceptions.html#exceptions.AttributeError>.
    This method should return the (computed) attribute value or raise an
    AttributeError
    <http://docs.python.org/library/exceptions.html#exceptions.AttributeError>
    exception. In order to avoid infinite recursion in this method, its
    implementation should always call the base class method with the
    same name to access any attributes it needs, for example,
    object.__getattribute__(self, name).

"""

But the point which for me is still unclear, is : does the default 
implementation of __getattribute__ (the one of "object") call 
__getattr__ by himself, or does it rely on its caller for that, by 
raising an AttributeError ? For Python2, it's blatantly the latter case 
which is favoured, but since it looks like an implementation detail at 
the moment, I propose we settle it (and document it) once for all.

>
>
> This list is not really an appropriate place to ask questions like 
> this though, comp.lang.python would be better.
>
> All the best,
>
> Michael Fooord
Sorry if I misposted, I just (wrongly ?) assumed that it was more an 
undecided, implementation-specific point (since the doc gave possible 
behaviours for __getattribute__, without precising which one was the 
default one), and thus targetted the hands-in-core-code audience only.

Regards,
Pascal


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20100320/851651d7/attachment-0001.html>


More information about the Python-Dev mailing list