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

自定义@property装饰器递归错误修复:不修改属性且保留实例访问

修复@property与__getattr__的递归错误问题

问题原因分析

调用y.var时,Y类的var属性将上下文切换为x实例,随后访问x.var;但X类本身没有var属性,会触发__getattr__方法去调用getattr(y, 'var'),形成y.var → x.var → y.var的无限循环,最终触发RecursionError。

修复方案(不修改Y的var属性、保留X对y的访问权限)

修改X类的__getattr__方法,加入递归调用检测,在发现循环依赖时抛出明确错误,避免栈溢出:

import inspect

class X(object):
    def __getattr__(self, name):
        # 遍历调用栈,检测是否存在重复的属性获取操作
        for frame in inspect.stack()[1:]:
            if frame.function == '__getattr__' and frame.locals.get('name') == name:
                raise RuntimeError(f"循环引用错误:无法获取属性 '{name}',X与Y实例的属性形成递归依赖")
        return getattr(y, name)
        
class Y(object):
    @property
    def var(self):
        self = x # 保留原有逻辑不修改
        return self.var
        
x, y = X(), Y()

print(y.var)
# 输出:RuntimeError: 循环引用错误:无法获取属性 'var',X与Y实例的属性形成递归依赖

补充说明

你提到这种递归本质上和Y类属性直接返回自身的情况等价,属于逻辑层面的正常错误。如果不想引入调用栈检测,也可以针对特定属性做判断,但上述方案更通用,既能保留X对y的其他属性访问权限,又能在出现循环时给出清晰的错误提示,替代模糊的栈溢出错误。

内容的提问来源于stack exchange,提问作者Marcin Tamiński

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 19:24:59