I'm trying to create a wrapper class and then overwrite __getattr__
so that requests for attributes that are not in the wrapper class are passed through into the inner object. Below is a toy example where I used a list as the inner object -
class A(object):
def __init__(self):
pass
def __getattr__(self, name):
print 'HERE'
return getattr(self.foo, name)
@property
def foo(self):
try:
return self._foo
except:
self._foo = [2, 1]
return self._foo
I would like to do something like
a = A()
a.sort() # initializes and sorts _foo
print a.foo
which prints [1, 2]
Finally, I need _foo
to initialized when foo
is called for the first time or when someone tries to get an attribute from A()
that is not in A
. Unfortunately, I'm getting in some sort of recursion and HERE
is being printed many times. Is what I want possible?
This
return getattr(self.foo, name)
is actually:
foo = self.foo
return getattr(foo, name)
Now self.foo
actually call this:
try:
return self._foo
which, since your class defines __getattr__
and - at least one the first call to self.foo
- doesn't have a _foo
attribute, calls self.__getattr__("_foo")
, which calls self.foo
, which etc etc etc...
Simple solution: make sure self._foo
is defined before (ie in the initializer) instead of trying to define it in foo()
.
You could also test for the existence of _foo
in the instance's dict, but that will break inheritance if _foo
is a computed attribute too - whether this is a problem or not depends on the context and concrete use case.
@property
def foo(self):
if '_foo' not in self.__dict__:
self._foo = [2, 1]
return self._foo
NB: I assume you made foo
a computed attribute to allow for lazy initialization of _foo
, else it makes little sense. If that's the case, you can also, quite simply, creates _foo
in the initializer with a sentinel value (usually None
, unless None
is a valid value for this attribute) and give it it's real value in foo()
.