【发布时间】: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;以及设置属性_temperature 的set_temperature 函数。
我所理解的是最后一行(赋值语句)必须运行代码property(get_temperature, set_temperature),该代码运行函数get_temperature 和set_temperature,并且实习生设置私有属性/属性_temperature。
此外,如果我运行:foo = Celsius(100),然后是 foo.temperature,foo.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