[Python-Dev] Attribute lookup ambiguity
Michael Foord
fuzzyman at voidspace.org.uk
Fri Mar 19 21:23:43 CET 2010
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
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
>
> Is that on purpose ? Considering that __getattribute__ (at lest,
> object.__getattribute__) does 90% of the hard job, why are these 10%
> left ?
> Can we find somewhere the details of "who must do what" when
> customizing attribute access ?
> Shouldn't we inform people about the fact that __getattribute__ isn't
> sufficient in itself to lookup an attribute ?
>
> Thanks for the attention,
> regards,
> Pascal
>
>
>
> =======
> INPUT
> =======
>
> class A(object):
>
> def __getattribute__(self, name):
> print "A getattribute", name
> return object.__getattribute__(self, name)
>
> def __getattr__(self, name):
> print "A getattr", name
> return "hello A"
>
>
> class B(A):
>
>
> def __getattribute__(self, name):
> print "B getattribute", name
> return A.__getattribute__(self, name)
>
> def __getattr__(self, name):
> print "B getattr", name
> return "hello B"
>
> print A().obj
> print "---"
> print B().obj
> print "---"
> print getattr(B(), "obj")
> print "-----"
> print object.__getattribute__(B(), "obj") # DOES NOT CALL
> __getattr__() !!!
>
>
> ===========
> OUTPUT
> ===========
>
> A getattribute obj
> A getattr obj
> hello A
> ---
> B getattribute obj
> A getattribute obj
> B getattr obj
> hello B
> ---
> B getattribute obj
> A getattribute obj
> B getattr obj
> hello B
> -----
> Traceback (most recent call last):
> File "C:\Users\Pakal\Desktop\test_object_model.py", line 34, in <module>
> print object.__getattribute__(B(), "obj") # DOES NOT CALL
> __getattr__() !!!???
> AttributeError: 'B' object has no attribute 'obj'
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> http://mail.python.org/mailman/options/python-dev/fuzzyman%40voidspace.org.uk
>
--
http://www.ironpythoninaction.com/
http://www.voidspace.org.uk/blog
READ CAREFULLY. By accepting and reading this email you agree, on behalf of your employer, to release me from all obligations and waivers arising from any and all NON-NEGOTIATED agreements, licenses, terms-of-service, shrinkwrap, clickwrap, browsewrap, confidentiality, non-disclosure, non-compete and acceptable use policies (”BOGUS AGREEMENTS”) that I have entered into with your employer, its partners, licensors, agents and assigns, in perpetuity, without prejudice to my ongoing rights and privileges. You further represent that you have the authority to release me from any BOGUS AGREEMENTS on behalf of your employer.
More information about the Python-Dev
mailing list