【问题标题】:Using Properties in Python classes cause "maximum recursion depth exceeded" [duplicate]在 Python 类中使用属​​性会导致“超出最大递归深度”[重复]
【发布时间】:2016-08-24 04:57:04
【问题描述】:

这是我编写的一个测试类,用于熟悉 Python 脚本中的 @propertiessetter 功能:

class Test(object):
    def __init__(self, value):
        self.x =  value
    @property
    def x(self):
        return self.x
    @x.setter
    def x(self, value):
        self.x = value

问题是当我想从我的类中创建一个对象时,我遇到了以下错误:

>>> t = Test(1)

Traceback (most recent call last):
  File "<pyshell#19>", line 1, in <module>
    t = Test(1)
  File "<pyshell#18>", line 3, in __init__
    self.x =  value
  File "<pyshell#18>", line 9, in x
    self.x = value
  File "<pyshell#18>", line 9, in x
  #A bunch of lines skipped
RuntimeError: maximum recursion depth exceeded
>>> 

【问题讨论】:

  • 使用self._x 而不是self.x 作为私人成员。通过同时命名成员和属性 x 属性阴影成员,并在 getter 正文中调用 return self.x

标签: python python-3.x python-2.7 class


【解决方案1】:

您对 getter、setter 和属性使用相同的名称。设置属性时,必须在本地重命名属性;惯例是在它前面加上下划线。

class Test(object):
    def __init__(self, value):
        self._x =  value

    @property
    def x(self):
        return self._x

【讨论】:

  • 谢谢。请查看Byte Commander 的回答here。他为settergettervariable 使用了相同的名称,但他的程序运行良好。
  • 如果已经定义了setter方法,最好只在getter/setter/deleter方法中访问私有变量self._x。在 __init__ 你可以说self.x = value
  • @Rob 我不确定这是否正确。为什么更好?这不是我所知道的约定。
  • 您正在实施 setter 方法是有原因的,可能是为了进行一些输入检查/操作。在对象实例化期间做同样的事情是有意义的。
  • 是的,完全正确。正如@Rob 所说,分配给__init__ 中的私有属性将绕过property setter 方法,因此不会应用其中包含的逻辑。在实例化过程中允许可能不同的值以及稍后在重新分配过程中允许可能存在不同的值可能是错误的或至少不一致。
【解决方案2】:

问题出在以下几行:

def x(self):
    return self.x

替换为

def get_x(self):
    return self.x

因为现在函数调用自己,导致超出递归深度。

【讨论】:

  • 我要使用@properties
猜你喜欢
  • 1970-01-01
  • 2022-12-19
  • 2021-10-14
  • 2011-12-31
  • 1970-01-01
  • 1970-01-01
  • 2014-05-02
  • 2011-01-24
  • 2023-03-15
相关资源
最近更新 更多