【问题标题】:Python - Property setting from list causes maximum recursion depth exceededPython - 列表中的属性设置导致超出最大递归深度
【发布时间】:2013-09-24 18:33:28
【问题描述】:

我有以下课程:

class vehicle(object):
    def __init__(self, name):
        self.name = name
        self.kinds_list = ["tank", "car", "motorbike", "bike", "quad" ] 

    @property
    def kind(self):
        return self.kind

    @kind.setter
    def kind(self, x):
        if x in self.kinds_list:
            self.kind = x
        else:
            raise AttributeError('No attribute {0} found !'.format(y))

设置 kind 会导致 超出最大递归深度,也就是堆栈溢出。

问:如何重写 setter 使其仅适用于固定列表?

【问题讨论】:

  • 您只需要某些允许的属性?也许您应该改为查看__slots__...或者__setattr__...也许如果您在一段中解释了您想要实现的目标...
  • 你意识到在setter中使用self.kind = x会再次调用setter吗?为基础属性和属性使用不同的名称。
  • @JonClements 虽然不是远程堆栈溢出的原因。您的建议在这种特定情况下很有用,但一般不会帮助 OP 正确使用 @property
  • 您的 getter 和 setter 是递归定义的(self.kind = x 再次调用 setter,等等)。改用“私有”属性,例如self._kind.
  • 另外,您使用选中的kinds_list 而不是仅仅定义继承自vehicleTankCar、[etc] 类是否有原因?

标签: python recursion


【解决方案1】:

您达到最大递归深度的原因是在您的设置器中,您执行self.kind = ...,它递归调用相同的设置器。您应该将该值存储为一些私有属性,只需将 self.kind 重命名为 self._kind

class vehicle(object):
    def __init__(self, name):
        self.name = name
        self.kinds_list = ["tank", "car", "motorbike", "bike", "quad" ] 

    @property
    def kind(self):
        return self._kind

    @kind.setter
    def kind(self, x):
        if x in self.kinds_list:
            self._kind = x
        else:
            raise ValueError('{0} is an illegal kind of vehicle!'.format(y))

这不是像其他语言那样真正的私有属性,因为没有什么可以阻止您访问my_vehicle._kind。按照 python 中的约定,以下划线开头的所有内容都是私有的,通常不应在类外触及。或者as they say:python 是为成年人同意的;)。

我还稍微修改了setter中的错误信息。

【讨论】:

  • 谢谢,已修复。 AttributeError 的主要用途可能在__getattribute__ 内部,当您尝试访问my_object.illegal_attribute 时。 ValueError 在这里似乎更合适。
  • 我只是在学习你现在最可能知道的。私有属性是接下来要学习的主题。谢谢!
  • 不要为还在学习新事物而道歉,每个人都是这样开始的。只需继续以聪明的方式提问(你已经这样做了),然后首先进行搜索以检查之前是否已经提出过问题(因为类似的事情have been asked before)。如果您满意,请采纳答案。
猜你喜欢
  • 2022-12-19
  • 2016-08-24
  • 2011-12-31
  • 1970-01-01
  • 1970-01-01
  • 2014-05-02
  • 2021-12-09
  • 2018-01-14
  • 2020-07-13
相关资源
最近更新 更多