如何正确重写__getattr__以访问Foo类中module实例的属性
解决Foo类属性代理的递归问题
你的代码陷入递归的原因是:__getattr__方法中调用的getattr(self, name),在属性不存在时会再次触发__getattr__,形成无限循环——因为当常规属性查找失败时,Python会自动调用__getattr__,而你在方法内又发起了相同的属性查找请求,导致递归调用无法终止。
正确实现方式
Python中__getattr__本身就是常规属性查找失败后的兜底方法,也就是说,只有当Foo实例自身、类及其父类中都找不到目标属性时,这个方法才会被执行。因此你不需要额外尝试获取self的属性,直接从module中代理即可:
class Foo(): def __init__(self, module): self.module = module def __getattr__(self, name): # 直接从module实例中获取目标属性 return getattr(self.module, name)
补充说明
- 如果
module也不存在该属性,getattr会自动抛出标准的AttributeError,和Python默认的属性报错逻辑一致。 - 如果你需要自定义报错信息,可以添加try-except块:
class Foo(): def __init__(self, module): self.module = module def __getattr__(self, name): try: return getattr(self.module, name) except AttributeError: raise AttributeError(f"'Foo' object has no attribute '{name}'") from None
内容的提问来源于stack exchange,提问作者jubueche
相关产品推荐
相关产品推荐

