【问题标题】:Trouble understanding private attributes in classes and the class property method in Python 3无法理解类中的私有属性和 Python 3 中的类属性方法
【发布时间】:2017-03-13 02:45:37
【问题描述】:

这个类的例子取自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 并直接进入最后一行的。在我看来,这里创建了三个属性/属性:Class 属性,temperature;实例属性,temperature;以及设置属性_temperatureset_temperature 函数。

我所理解的是最后一行(赋值语句)必须运行代码property(get_temperature, set_temperature),该代码运行函数get_temperatureset_temperature,并且实习生设置私有属性/属性_temperature

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

更多问题...

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

为什么我们需要私有属性/属性而不仅仅是温度?

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

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

【问题讨论】:

  • Celcius.temperature 被定义为property 时,它会覆盖语句self.temperature = ... 的行为,而是调用setter 函数set_temperature,因此永远不会有一个名为temperature 的实例变量集.
  • 它怎么知道覆盖self.temperature = temperature这个语句?因为他们都有相同的名字,温度?
  • 是的,但更具体地说,因为您已经在类中定义了一个描述符,所以当您在实例上执行任何具有相同名称的操作时,描述符会处理实际发生的事情。与方法完全相同,如果您运行print(self.get_temperature),它会显示bound_method 对象而不是函数本身,这是因为函数也是描述符。
  • 这不是重复的。我正在使用一个更真实的例子来说明这些概念。在你提到它之前,我什至不知道描述符是什么。我是新手,鉴于您引用的答案,我需要更多解释。

标签: class python-3.x namespaces decorator private-members


【解决方案1】:

当我们第一次被告知类/对象/属性时,我们经常被告知这样的话:

当您查找像 x.foo 这样的属性时,它首先会查看是否 'foo' 是一个实例变量并返回它,如果不是它检查是否 'foo'x 的类中定义并返回,否则返回 AttributeError 被提出。

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

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

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

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

我建议你试试stepping through your code in pythontutor,它会准确地告诉你get_temeratureset_temperature 在哪些语句之后被调用。

【讨论】:

  • 我还想参考一篇很棒的文章,它帮助我了解here 发生了什么。谢谢!
猜你喜欢
  • 2013-08-16
  • 1970-01-01
  • 2011-02-13
  • 2016-04-24
  • 2015-02-24
  • 1970-01-01
  • 2021-08-08
  • 1970-01-01
  • 2014-06-19
相关资源
最近更新 更多