python __getattribute__ 返回 class 变量属性时出现递归错误
python __getattribute__ RecursionError when returning class variable attribute
为什么 Foo2 在 __getattribute__
中导致 getattr
无限递归调用 class 变量,但 Foo 在 __getattr__
中进行相同的调用却工作正常?关于如何让 Foo2 工作有什么建议吗?
class Foobar(object):
def __init__(self):
super().__init__()
self.bar = 5
def getbar(self):
return self.bar
class Foo(object):
def __init__(self):
super().__init__()
self.__foo = Foobar()
def __getattr__(self, attr):
return getattr(self.__foo, attr)
class Foo2(object):
def __init__(self):
super().__init__()
self.__foo = Foobar()
def __getattribute__(self, attr):
try:
return getattr(self.__foo, attr)
except AttributeError:
super().__getattribute__(attr)
if __name__ == '__main__':
foo = Foo()
foo2 = Foo2()
print(foo.bar, foo.getbar()) # Works as expected
try:
print(foo2.bar, foo2.getbar()) # Doesn't work
except RecursionError:
print('Why does Foo2 result in RecursionError. How to fix?')
设置:Windows10,Python3.7
__getattribute__
方法被无条件调用以查找 object 上的所有属性,而不仅仅是不存在的属性(__getattr__
就是这样做的)。当您在其实现中执行 self.__foo
时,您会递归,因为 __foo
是我们试图在 object.
上查找的另一个属性
为避免此问题,您需要调用 parent 的 __getattribute__
方法以在 __getattribute__
方法中获取您自己的所有属性:
def __getattribute__(self, attr):
try:
return getattr(super().__getattribute__("_Foo__foo"), attr)
except AttributeError:
super().__getattribute__(attr)
请注意,我必须手动对 __foo
属性应用名称修改,因为我们需要将名称作为字符串传递给 super().__getattribute__
。这可能表明您一开始就不应该进行处理。带有单个前导下划线的名称可能是更好的选择。
为什么 Foo2 在 __getattribute__
中导致 getattr
无限递归调用 class 变量,但 Foo 在 __getattr__
中进行相同的调用却工作正常?关于如何让 Foo2 工作有什么建议吗?
class Foobar(object):
def __init__(self):
super().__init__()
self.bar = 5
def getbar(self):
return self.bar
class Foo(object):
def __init__(self):
super().__init__()
self.__foo = Foobar()
def __getattr__(self, attr):
return getattr(self.__foo, attr)
class Foo2(object):
def __init__(self):
super().__init__()
self.__foo = Foobar()
def __getattribute__(self, attr):
try:
return getattr(self.__foo, attr)
except AttributeError:
super().__getattribute__(attr)
if __name__ == '__main__':
foo = Foo()
foo2 = Foo2()
print(foo.bar, foo.getbar()) # Works as expected
try:
print(foo2.bar, foo2.getbar()) # Doesn't work
except RecursionError:
print('Why does Foo2 result in RecursionError. How to fix?')
设置:Windows10,Python3.7
__getattribute__
方法被无条件调用以查找 object 上的所有属性,而不仅仅是不存在的属性(__getattr__
就是这样做的)。当您在其实现中执行 self.__foo
时,您会递归,因为 __foo
是我们试图在 object.
为避免此问题,您需要调用 parent 的 __getattribute__
方法以在 __getattribute__
方法中获取您自己的所有属性:
def __getattribute__(self, attr):
try:
return getattr(super().__getattribute__("_Foo__foo"), attr)
except AttributeError:
super().__getattribute__(attr)
请注意,我必须手动对 __foo
属性应用名称修改,因为我们需要将名称作为字符串传递给 super().__getattribute__
。这可能表明您一开始就不应该进行处理。带有单个前导下划线的名称可能是更好的选择。