无法理解 classes 中的私有属性和 Python 中的 class 属性 方法 3

Trouble understanding private attributes in classes and the class property method in Python 3

此 class 示例取自 here

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

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

    def get_temperature(self):
        print("Getting value")
        return self._temperature

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

    temperature = property(get_temperature, set_temperature)

这里的想法是,当我们创建 Celsius 的实例并设置温度属性时(例如 foo = Celsus (-1000) ),我们希望在设置之前确保该属性不小于 -273温度属性。

不明白怎么好像绕过了self.temperature = temperature直接到了最后一行。在我看来,这里创建了三个 attributes/properties:Class 属性,temperature;实例属性,temperature;以及设置属性 _temperatureset_temperature 函数。

我所理解的是最后一行(赋值语句)必须 运行 代码 property(get_temperature, set_temperature) 其中 运行 函数 get_temperatureset_temperature 和实习生设置私人 attribute/property _temperature

此外,如果我 运行: foo = Celsius(100) 然后 foo.temperaturefoo.temperature 的结果如何来自 temperature = property(get_temperature, set_temperature) 从而 _temperature 而不是 self.temperature = temperature?如果每次调用 foo.temperaturetemperature = property(get_temperature, set_temperature) 得到 运行,为什么还要 self.temperature = temperature

更多问题...

为什么我们有两个同名的属性(例如温度),代码如何知道在调用 foo.temperature 时检索 _temperature 的值?

为什么我们需要私人 attributes/properties 而不仅仅是温度?

set_temperature(self, value)如何获取参数value的属性(例如替换value的参数)?

简而言之,请像一个三岁的孩子一样向我解释这个,因为我才编程几个月。提前致谢!

当我们第一次学习 classes/objects/attributes 时,我们经常被告知这样的事情:

When you look up an attribute like x.foo it first looks to see if 'foo' is an instance variable and returns it, if not it checks if 'foo' is defined in the class of x and returns that, otherwise an AttributeError is raised.

这描述了大部分时间发生的情况,但没有为descriptors留出空间。因此,如果您目前认为以上是关于属性查找的全部内容 property,而其他描述符似乎是这些规则的 例外。

描述符基本上定义了在查找/设置某个实例的属性时要做什么,property 是一种实现,可让您定义自己的函数以在获取/设置/删除属性时调用。

当您执行 temperature = property(get_temperature, set_temperature) 时,您指定当 x.temperature 检索时 它应该调用 x.get_temperature() 和 return该调用的值将是 x.temperature 的计算结果。

通过将 set_temperature 指定为 属性 的 setter,它表示每当 x.temperature 分配 给某物它应该调用 set_temperature 并将指定的值作为参数。

我建议您尝试 stepping through your code in pythontutor,它会准确显示 get_temeratureset_temperature 是在哪些语句之后调用的。