Ulrich Eckhardt wrote: > Peter Otten wrote: >> Use getattr() >> >>>>> class W(object): >> ... def __init__(self, wrapped): self._wrapped = wrapped >> ... def __getattr__(self, name): >> ... return getattr(self._wrapped, name) >> ... > > I thought there was something like this, thanks! :) > > When I read this, I thought "OK, now I only have check first if the > attribute can be looked up in 'self' first", but even that isn't the case.
The getattr() call inside __getattr__() raises an AttributeError if it can't find an attribute called name in self._wrapped. This very thing you'd have to do if you wanted to signal that an attribute doesn't exist, like in >>> class A: ... def __getattr__(self, name): ... if name == "foo": return 42 ... raise AttributeError ... >>> a = A() >>> a.foo 42 >>> a.bar Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 4, in __getattr__ AttributeError > I tried it and added another function to class W above, which I can call > just as if it was defined in _wrapped, so obviously (?) the __getattr__ > lookup isn't done there. > > So, short follow-up question: Why does this work? __getattr__() is a fallback that is only tried when the normal lookup fails. If you need to intercept every attribute lookup use __getattribute__() instead: >> class A(object): ... def __getattr__(self, name): ... print "__getattr__(%r)" % name ... return 42 ... def __getattribute__(self, name): ... print "__getattribute__(%r)" % name ... return super(A, self).__getattribute__(name) ... >>> a = A() >>> a.foo = "yadda" >>> a.foo __getattribute__('foo') 'yadda' >>> a.bar __getattribute__('bar') __getattr__('bar') 42 Peter -- http://mail.python.org/mailman/listinfo/python-list