【问题标题】:@property gets writeable when attribute is of dict type当属性是 dict 类型时,@property 变得可写
【发布时间】:2015-09-23 10:25:32
【问题描述】:

@属性定义为int

以下代码取自Python Docs:

class Parrot(object):
    def __init__(self):
        self._voltage = 100000

    @property
    def voltage(self):
        """Get the current voltage."""
        return self._voltage

当我跑步时:

parrot = Parrot()
print(parrot.voltage)
parrot.voltage = 100
print(parrot.voltage)

我得到以下输出(正如预期的那样,因为没有定义 setter)

{0: 100000}
Traceback (most recent call last):
   File "prop.py", line 13, in <module>
     parrot.voltage = 100
 AttributeError: can't set attribute

@属性定义为dict

但是,如果我定义self._voltage = {},则属性变为可写:

class Parrot(object):
    def __init__(self):
        self._voltage = {}
        self._voltage[0] = 100000

    @property
    def voltage(self):
        """Get the current voltage."""
        return self._voltage

parrot = Parrot()
print(parrot.voltage)
parrot.voltage[0] = 100
print(parrot.voltage)

那么输出是:

{0: 100000}
{0: 100}

Python 2.7.9 和 Python 3.4.3 中的行为相同。为什么属性是可写的,即使代码中没有明确定义 setter? Here 建议继承 dict 以获得这种行为。但是,这似乎不是必需的。

【问题讨论】:

  • 因为现在您正在更新 getter 返回的对象。属性只会处理parrot.voltage = 100 而不是parrot.voltage[0] = 100。
  • 您没有设置属性。你正在改变一个可变对象。与任何其他可以变异的对象相同;列出,设置,另一个自定义类实例。

标签: python dictionary properties setter


【解决方案1】:

您没有设置属性。您正在操作一个可变对象。

分配不是在属性本身上,而是在订阅上,[..] 部分寻址字典键。您可以将属性分配给一个新名称并仍然操作该字典:

parrot = Parrot()
parrot_voltage = parrot.voltage
parrot_voltage[0] = 100

但您不能将属性设置为新字典或完全不同类型的对象。这适用于属性中使用的所有可变对象;列表、集合、实例等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-28
    • 2012-04-13
    • 1970-01-01
    • 2013-05-22
    • 2011-05-30
    • 1970-01-01
    • 2016-12-11
    相关资源
    最近更新 更多