Python 忽略 setter

Python ignores setter

我是 python 的新手,我尝试用 get/set 创建一个 class 作为 属性。我从互联网上复制了一个简单的例子,似乎 Python 忽略了我的 setter。我是不是在做一些非常愚蠢的事情,因为我不明白为什么它不起作用。

我是 运行 python 2.6.6 Linux。

谢谢

#!/usr/bin/python

class Celsius:
    def __init__(self, temperature = 0):
        self._temperature = temperature

    def to_fahrenheit(self):
        return (self.temperature * 1.8) + 32

    @property
    def temperature(self):
        print("Getting value")
        return self._temperature

    @temperature.setter
    def temperature(self, value):
        if value < -273:
            raise ValueError("Temperature below -273 is not possible")
        print("Setting value")
        self._temperature = value

c = Celsius()

c.temperature = -5555

print c.temperature

我在命令行中唯一看到的是它打印 -5555。它完全忽略了我的 setter.

这让我发疯,有什么想法吗?

问题是您将 Celsius 定义为 old-style class

property 的文档非常清楚:

Return a property attribute for new-style classes (classes that derive from object).

这样做的原因是 @property 通过构建 descriptor 来工作,并且,正如新式 classes 上的文档所说:

The major motivation for introducing new-style classes is to provide a unified object model with a full meta-model. It also has a number of practical benefits, like the ability to subclass most built-in types, or the introduction of “descriptors”, which enable computed properties.


要解决此问题,只需继承 object:

,使 Celsius 成为新样式 class
class Celsius(object):
    # all the rest of your code is the same.

当然如果你升级到Python3,问题就消失了,因为所有 class都是新式的class es。特别是,如果您不指定任何其他基数 class,您会得到 object 作为基数 class、1 所以 class Spam:class Spam():class Spam(object): 在 3.x 中的含义与 class Spam(object): 在 2.x 中的含义相同。


1.这实际上是幕后的两个变化。首先,class 语句总是编译为对 metaclass 的调用,而不是特殊的旧式 class 构造。其次,默认的 metaclass,type,如果你传递一个空的碱基列表,它会填充 (object,)。但是你很少需要理解这些东西,这就是为什么它在脚注中会伤害你的眼睛。