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

为何对象描述符的内部属性名需与原名称不同?递归错误解惑

为什么描述符内部名称要和原属性名不同?

递归错误的根源

当你在类中定义描述符属性(比如class MyClass: foo = x()),Python会将类层面的foo识别为描述符。当访问实例的foo属性(如obj.foo)时,Python会自动触发描述符的__get__方法。

在你最初的代码里,__set_name__将internal_name设为和属性名完全相同的字符串(比如属性名是foo,internal_name就是foo)。这导致__get__方法中执行getattr(instance, self.internal_name)时,相当于再次访问obj.foo——而这个操作又会触发描述符的__get__方法,形成无限递归,直到超过Python的递归深度限制,抛出RecursionError。

修改后解决问题的原理

将internal_name改为f'_{name}'(比如属性名是foo,internal_name变成_foo)后,getattr(instance, '_foo')访问的是实例自身存储的普通属性,而非绑定了描述符的公开属性。这个带下划线的属性并没有关联描述符逻辑,所以直接返回存储的值,不会再次触发__get__,递归也就终止了。

本质上,这是描述符的常规设计思路:用公开属性名(如foo)挂载描述符逻辑,用带前缀的内部名称(如_foo)存储实际值,避免属性名冲突导致的递归调用。

内容的提问来源于stack exchange,提问作者Tim Sananikone

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 16:25:04