[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