【问题标题】:Python ignores setterPython 忽略 setter
【发布时间】:2018-06-19 18:48:41
【问题描述】:

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

我在 Linux 上运行 python 2.6.6。

谢谢

#!/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。它完全忽略了我的二传手。

这快把我逼疯了,有什么想法吗?

【问题讨论】:

  • 属性不适用于旧式类。如果您没有从其他任何东西继承,则从 object 继承。
  • 2018 年你有理由需要使用 Python 2.6 吗? Python 2.7,我可以理解,但 2.6 已经过了 EOL 大约 6 年了,我认为最后一个保持向后支持的发行版 LTS 在今年早些时候到期。

标签: python object attributes python-2.x python-2.6


【解决方案1】:

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

property 的文档非常清楚地说明了这一点:

返回新样式类(派生自object 的类)的属性属性。

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

引入新型类的主要动机是提供一个具有完整元模型的统一对象模型。它还具有许多实际优势,例如能够对大多数内置类型进行子类化,或引入启用计算属性的“描述符”。


要解决这个问题,只需通过继承 object 使 Celsius 成为一个新样式的类:

class Celsius(object):
    # all the rest of your code is the same.

当然,如果您升级到 Python 3,问题就消失了,因为 所有 类都是新样式的类。特别是,如果你不指定任何其他基类,你会得到object 作为基类,1 所以class Spam:class Spam():class Spam(object): 都意味着同样的事情在 3.x 中,class Spam(object): 在 2.x 中的意思。


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

【讨论】:

  • @user3483203 是的。让我更新答案以使其更清楚。
  • 该死,我花了一个下午,我所要做的就是添加(对象)。谢谢!
猜你喜欢
  • 2014-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 2021-03-27
  • 1970-01-01
  • 2018-07-05
  • 2017-06-01
相关资源
最近更新 更多