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

未使用私有成员时Python出现递归错误的原因咨询

问题解析:Python属性设置中的递归错误与私有成员作用

错误代码示例

class Product:
    def __init__(self, price):
        self.setprice(price)
    def getprice(self):
        return self.price
    def setprice(self, value):
        if value < 0:
            raise ValueError("Price cannot be negative")
        self.price = value
price = property(getprice, setprice)

x = Product(23)
print(x.price)

报错信息

File "c:\Users\OneDrive\Desktop\PYTHON\tempCodeRunnerFile.py", line 9, in setprice
    self.price = value
[Previous line repeated 993 more times]
File "c:\Users\OneDrive\Desktop\PYTHON\tempCodeRunnerFile.py", line 7, in setprice
    if value < 0:
RecursionError: maximum recursion depth exceeded in comparison

修正后的代码示例

class Product:
    def __init__(self, price):
        self.setprice(price)
    def getprice(self):
        return self.__price
    def setprice(self, value):
        if value < 0:
            raise ValueError("Price cannot be negative")
        self.__price = value
price = property(getprice, setprice)

x = Product(23)
print(x.price)

错误原因

你通过price = property(getprice, setprice)已经把类的price属性绑定到了getprice和setprice方法上。当在setprice里执行self.price = value时,Python不会直接给实例添加名为price的属性,而是会触发你绑定的setprice方法。

这就形成了无限递归:调用setprice → 执行self.price = value → 再次触发setprice → 又执行self.price = value……直到超过Python的递归深度限制,抛出RecursionError。

同理,getprice里的return self.price也会触发getprice方法导致递归,只是报错在设置阶段先被触发了。

为什么要使用私有成员

把内部存储变量改成self.__price(私有成员),就能避免和类的price属性(由property创建)重名。

当执行self.__price = value时,Python会将这个变量处理为名称改写后的私有属性(实际存储为_Product__price),不会触发price属性对应的setprice方法,而是直接给实例赋值。这样就切断了递归链,让方法正常工作:

  • setprice负责校验值的合法性,然后将值存入私有成员__price
  • getprice直接从私有成员__price读取值
  • 外部通过x.price访问时自动调用getprice,赋值时自动调用setprice,实现了属性的封装和校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 22:55:18