[Python-Dev] Attribute lookup ambiguity (original) (raw)

Pascal Chambon chambon.pascal at wanadoo.fr
Fri Mar 19 19:58:42 CET 2010


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.

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 print object.getattribute(B(), "obj") # DOES NOT CALL getattr() !!!??? AttributeError: 'B' object has no attribute 'obj'



More information about the Python-Dev mailing list