【问题标题】:Unable to Set Python @Property无法设置 Python @Property
【发布时间】:2020-03-04 15:39:56
【问题描述】:

我正在使用原始数据创建一个 python 类,如下所示:

Class Test:

def __init__(self, raw_number):
    self._raw_number = raw_number

然后我将_raw_number 计算为属性以返回我想要的实际数字:

@property
def number(self):
    return self._raw_number[0]

但是,当尝试在 Test 对象上设置此属性时,使用

t = Test([1, 2, 3]) # this will set the number property to 1
t.number = 5 # this is supposed to set the number property to 5

我遇到了一个错误,上面写着property number cannot be set

我想知道为什么我可以解决这个问题?

【问题讨论】:

  • 您定义了一个“get”属性,但没有定义“set”属性。查看property 文档以了解其工作原理。
  • 最后一个链接不适用于我的情况,因为我没有在 init 函数中定义属性(甚至是同名的私有属性)。

标签: python class properties


【解决方案1】:

@property 本身(至少在如图所示使用时)仅提供一个 getter。除非您也提供 setter,否则该属性是只读的。

class Test:

    def __init__(self, raw_number):
        self.number = raw_number

    @property
    def number(self):
        return self._raw_number[0]

    @number.setter
    def number(self, value):
        self._raw_number = value

请记住,setter 应该负责确保 _raw_number 的值实际上是可索引的。此外,__init__ 方法可以使用 初始化属性的setter;只有 getter 和 setter 本身才能访问底层的 _raw_number 属性。


property可以同时设置getter和setter。

class Test:
    def __init__(self, raw_number):
        self.number = raw_number

    def _getter(self):
        return self._raw_number[0]

    def _setter(self, value):
        try:
            value[0]
        except IndexError:
            raise TypeError("Value must be indexable")
        self._raw_number = value

    number = property(_getter, _setter)

    # Clean up the namespace before creating the class
    del _getter
    del _setter

【讨论】:

  • 所以这与我尝试做的类似。但是,我遇到的问题是第一次计算 number 时,它是基于数组的。但是下一次我设置数字时,比如number = number * 5,我传入了两个整数。这不会影响吸气剂吗?
  • 是的; getter 和 setter 需要一起设计,以确保 setter 提供 getter 可以使用的值。这是否意味着 setter 应该 requirereject 列表是一个设计问题。
  • 好的,所以基本上你的意思是这是一个设计问题,没有什么我可以通过代码解决的问题?我将不得不重新设计我的班级如何处理财产?
  • 是的;目前尚不清楚为什么当 getter 只需要第一个值时将其初始化为列表。在_setter 中,如果给定的值不能与self._raw_number[0] 一起使用,我只会让它引发错误。
  • 另一种选择是一个简单地做类似self._raw_number[0] = value的事情的setter。但归根结底,第一步是决定您希望财产如何表现;完成此操作后,您可以实现 getter 和 setter 以提供该行为。
猜你喜欢
  • 2013-11-17
  • 2019-05-23
  • 2014-09-15
  • 1970-01-01
  • 1970-01-01
  • 2018-11-23
  • 2017-09-02
  • 2011-11-20
  • 1970-01-01
相关资源
最近更新 更多