Python中返回字典元素时如何避免递归错误?
解决Python字典转类属性时的递归错误
原代码试图将字典元素作为类属性直接访问,但运行时会触发递归深度超出错误,问题根源和解决方法如下:
错误原因
__init__方法里先执行print(self.x),此时self.x不存在,Python会调用__getattr__尝试获取该属性。- 进入
__getattr__后,代码要判断item是否在self.metadata中,但此时__init__还没执行到self.metadata = {...}这一行,self.metadata同样是未定义属性,于是再次触发__getattr__调用。 - 这就形成了无限递归:
print(self.x)→ 调用__getattr__('x')→ 访问self.metadata→ 调用__getattr__('metadata')→ 再次访问self.metadata……直到超出递归深度限制。
解决方法
方法一:调整初始化顺序(推荐)
把self.metadata的赋值放在属性访问之前,确保调用__getattr__时字典已经存在:
class MyClass: def __init__(self): self.metadata = { "a": 42, "b": 1, } print(self.x) # 此时x不存在会调用__getattr__,metadata已完成初始化 def __getattr__(self, item): if item in self.metadata: return self.metadata[item] else: raise AttributeError(f"No attribute {item} found.") # 遵循Python规范,属性不存在抛AttributeError test = MyClass() # 会抛出AttributeError(x不在metadata中),但不会触发递归错误
方法二:在__getattr__中优先处理metadata
如果不想调整初始化顺序,可以在__getattr__里先判断目标是否为metadata,提前终止递归:
class MyClass: def __init__(self): print(self.x) self.metadata = { "a": 42, "b": 1, } def __getattr__(self, item): if item == 'metadata': # 此时metadata未初始化,直接抛错阻止递归 raise AttributeError(f"'MyClass' object has no attribute '{item}'") if item in self.metadata: return self.metadata[item] else: raise AttributeError(f"No attribute {item} found.") # 注意:这种方式下print(self.x)会先触发AttributeError,因为metadata还未创建
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

