python - 返回类变量属性时的python __getattribute__ RecursionError
问题描述
为什么 Foo2 会导致getattr
类变量 in的无限递归调用__getattribute__
,但 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?')
设置:Windows 10、Python 3.7
解决方案
该__getattribute__
方法被无条件地调用以查找对象上的所有属性,而不仅仅是那些不存在的属性(这是什么__getattr__
)。当你self.__foo
在它的实现中这样做时,你会递归,因为__foo
这是我们试图在对象上查找的另一个属性。
为避免此问题,您需要调用父级的__getattribute__
方法来获取方法内的所有您自己的属性__getattribute__
:
def __getattribute__(self, attr):
try:
return getattr(super().__getattribute__("_Foo__foo"), attr)
except AttributeError:
super().__getattribute__(attr)
请注意,我必须手动将名称修饰应用于__foo
属性,因为我们需要将名称作为字符串传递给super().__getattribute__
. 这可能表明你不应该首先进行修改。带有单个前导下划线的名称可能是更好的选择。
推荐阅读
- node.js - 保护节点密码
- android - `,**` 对 R8 和 ProGuard 有何改变?
- android - 有没有办法仅在特定短语上显示“浮动文本操作”?
- r - 闪亮的模块和 R Leaflet suspendWhenHidden 不重绘地图
- reactjs - 如何处理 react.js 的 package.json 中的停放域?
- javascript - 我正在用 Javascript 刷新我的技能
- xamarin.forms - Xamarin Form iOS 实现中导航栏中的文本颜色不正确
- snowflake-cloud-data-platform - 雪花 CDC 从 S3 到雪花
- java - 制作游戏板:如何缩短创建数组的代码,如何打印出来?
- azure-devops - Azure DevOps 扩展 - 更改扩展类别