Question

class Shadow(object):
    pass

class Test(object):
    a = 1
    b = 2

    _shadow = Shadow()

    def __getattribute__(self, name):
        try:
            return object.__getattribute__(self._shadow, name)
        except: print "not shadowed"
        return object.__getattribute__(self, name)

With the above piece of code I would like to implement the following behavior:

>>>t = Test()
>>>t.a
1
>>>t._shadow.a = 17
>>>t.a
17
>>>t.b
2

The code works, but it will print "not shadowed" M-times (until recursion depth is reached). The question is why, there shouldn't be any recursion involved, I'm calling object.__getattribute__ and not self.__getattribute__.

Was it helpful?

Solution

__getattribute__ is called for all attribute access, including for self._shadow. But since you have __getattribute__ overridden, self._shadow triggers an infinite recursion.

The only work-around for that is to use object.__getattribute__, or better, super(Test, self).__getattribute__, to retrieve the _shadow attribute:

class Test(object):
    a = 1
    b = 2

    _shadow = Shadow()

    def __getattribute__(self, name):
        shadow = super(Test, self).__getattribute__('_shadow')
        try:
            return getattr(shadow, name)
        except AttributeError:
            print "not shadowed"
        return super(Test, self).__getattribute__(name)

There is no need to use object.__getattribute__ for the attribute access on the shadow object. Don't use Pokemon-style exception handling (you don't want to catch them all); catch only the specific AttributeError exception here.

Demo:

>>> t = Test()
>>> t.a
not shadowed
1
>>> t._shadow.a = 42
not shadowed
>>> t.a
42

Note that here too, accessing t._shadow triggers the 'not shadowed' message as it goes through the __getattribute__ handler.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top