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

Python 3.6.5中@property装饰器初始化时触发无限循环问题求助

解决@property装饰器导致的无限循环问题

嘿,我看到你在给自定义Duck类用@property的时候踩了无限循环的坑——这可是刚上手属性装饰器时超级常见的“新手陷阱”,我来帮你捋清楚问题出在哪,以及怎么修复!

问题根源

你现在的代码里,不管是@property修饰的获取方法,还是@name.setter修饰的赋值方法,都直接操作了self.name:

  • 当你调用self.name时,会触发@property的获取逻辑,而获取方法里又写了self.name,这就会无限递归调用获取方法;
  • 同样,赋值方法里的self.name = name会触发赋值逻辑本身,也会无限递归下去,最终导致栈溢出报错。

正确的写法示例

我们需要用一个约定俗成的私有变量(通常在变量名前加下划线_)来存储实际的name值,这样在getter和setter里操作这个私有变量,就不会触发属性的get/set逻辑了:

class Duck(object):
    def __init__(self, name):
        # 用带下划线的变量存储实际值,这是Python里表示“私有”的约定
        self._name = name
    
    @property
    def name(self):
        print("Quack! My name is", self._name)
        # 别忘了返回值,不然获取name时会得到None
        return self._name
    
    @name.setter
    def name(self, name):
        print("I've decided to change my name into", name, ".")
        print("So please call me", name, "from now on! Quack!")
        # 赋值给私有变量,不会触发setter递归
        self._name = name

关键细节说明

  • __init__里初始化的是self._name,而不是self.name:如果直接写self.name = name,会触发setter方法(当然如果初始化时想走setter逻辑也可以这么写,但直接赋值私有变量更高效);
  • getter方法必须返回self._name:不然当你执行print(duck.name)时,虽然会打印内容,但输出的结果是None,这肯定不是你想要的;
  • setter方法赋值给self._name:这样就不会再次触发setter,完美打破无限循环的闭环。

测试验证效果

你可以跑这段测试代码看看修复后的效果:

# 创建鸭子实例
donald = Duck("Donald")
# 调用getter获取名字
donald.name
# 修改名字,调用setter
donald.name = "Daffy"
# 再次获取名字
donald.name

运行后会输出:

Quack! My name is Donald
I've decided to change my name into Daffy .
So please call me Daffy from now on! Quack!
Quack! My name is Daffy

内容的提问来源于stack exchange,提问作者NeoZoom.lua

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:05:22