You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中返回字典元素时如何避免递归错误?

解决Python字典转类属性时的递归错误

原代码试图将字典元素作为类属性直接访问,但运行时会触发递归深度超出错误,问题根源和解决方法如下:

错误原因

  1. __init__方法里先执行print(self.x),此时self.x不存在,Python会调用__getattr__尝试获取该属性。
  2. 进入__getattr__后,代码要判断item是否在self.metadata中,但此时__init__还没执行到self.metadata = {...}这一行,self.metadata同样是未定义属性,于是再次触发__getattr__调用。
  3. 这就形成了无限递归: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 01:12:05