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
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com