delegate functions to member
Peter Otten
__peter__ at web.de
Tue Aug 10 07:17:47 EDT 2010
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
More information about the Python-list
mailing list