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)
使用上面的代码我想实现以下行为:
>>>t = Test()
>>>t.a
1
>>>t._shadow.a = 17
>>>t.a
17
>>>t.b
2
代码有效,但它会打印“未被遮蔽”的M次(直到达到递归深度)。问题是为什么,不应该涉及任何递归,我正在调用object.__getattribute__
而不是self.__getattribute__
。
答案 0 :(得分:2)
__getattribute__
用于所有属性访问,包括self._shadow
。但是,由于您__getattribute__
被覆盖,self._shadow
会触发无限递归。
唯一的解决方法是使用object.__getattribute__
或更好的super(Test, self).__getattribute__
来检索_shadow
属性:
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)
无需使用object.__getattribute__
对阴影对象进行属性访问。不要使用口袋妖怪式的异常处理(你不想全部捕获它们);此处仅捕获特定的AttributeError
例外。
演示:
>>> t = Test()
>>> t.a
not shadowed
1
>>> t._shadow.a = 42
not shadowed
>>> t.a
42
请注意,访问t._shadow
时,'not shadowed'
会在__getattribute__
处理程序中触发{{1}}消息。