在本教程中,您将学习 Python @property
装饰器。 在面向对象程序设计中使用获取器和设置器的 pythonic 方式。

Python 编程为我们提供了一个内置的@property
装饰器,使面向对象编程中的获取器和设置器的使用变得更加容易。
在详细介绍@property
装饰器是什么之前,让我们首先了解一下为什么首先需要使用它。
没有获取器和设置器的类
让我们假设我们决定制作一个类,该类存储以摄氏度为单位的温度。 它还将实现一种将温度转换为华氏度的方法。 一种方法如下:
1 2 3 4 5 6 |
<span class="pl-k">class</span> <span class="pl-v">Celsius</span>: <span class="pl-k">def</span> <span class="pl-en">__init__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">temperature</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>): <span class="pl-s1">self</span>.<span class="pl-s1">temperature</span> <span class="pl-c1">=</span> <span class="pl-s1">temperature</span> <span class="pl-k">def</span> <span class="pl-en">to_fahrenheit</span>(<span class="pl-s1">self</span>): <span class="pl-k">return</span> (<span class="pl-s1">self</span>.<span class="pl-s1">temperature</span> <span class="pl-c1">*</span> <span class="pl-c1">1.8</span>) <span class="pl-c1">+</span> <span class="pl-c1">32</span> |
我们可以根据需要创建对象,并根据需要操纵temperature
属性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<span class="pl-c"># Basic method of setting and getting attributes in Python</span> <span class="pl-k">class</span> <span class="pl-v">Celsius</span>: <span class="pl-k">def</span> <span class="pl-en">__init__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">temperature</span><span class="pl-c1">=</span><span class="pl-c1">0</span>): <span class="pl-s1">self</span>.<span class="pl-s1">temperature</span> <span class="pl-c1">=</span> <span class="pl-s1">temperature</span> <span class="pl-k">def</span> <span class="pl-en">to_fahrenheit</span>(<span class="pl-s1">self</span>): <span class="pl-k">return</span> (<span class="pl-s1">self</span>.<span class="pl-s1">temperature</span> <span class="pl-c1">*</span> <span class="pl-c1">1.8</span>) <span class="pl-c1">+</span> <span class="pl-c1">32</span> <span class="pl-c"># Create a new object</span> <span class="pl-s1">human</span> <span class="pl-c1">=</span> <span class="pl-v">Celsius</span>() <span class="pl-c"># Set the temperature</span> <span class="pl-s1">human</span>.<span class="pl-s1">temperature</span> <span class="pl-c1">=</span> <span class="pl-c1">37</span> <span class="pl-c"># Get the temperature attribute</span> <span class="pl-en">print</span>(<span class="pl-s1">human</span>.<span class="pl-s1">temperature</span>) <span class="pl-c"># Get the to_fahrenheit method</span> <span class="pl-en">print</span>(<span class="pl-s1">human</span>.<span class="pl-en">to_fahrenheit</span>()) |
输出
1 2 |
<span class="pl-c1">37</span> <span class="pl-c1">98.60000000000001</span> |
转换为华氏温度时,多余的小数位是由于浮点运算错误。 要了解更多信息,请访问 Python 浮点算术错误。
每当我们如上所述分配或检索任何对象属性(如temperature
)时,Python 都会在对象的内置__dict__
字典属性中进行搜索。
1 2 |
<span class="pl-c1">>></span><span class="pl-c1">></span> <span class="pl-s1">human</span>.<span class="pl-s1">__dict__</span> {<span class="pl-s">'temperature'</span>: <span class="pl-c1">37</span>} |
因此,man.temperature
在内部变为man.__dict__['temperature']
。
使用获取器和设置器
假设我们要扩展上面定义的Celsius
类的可用性。 我们知道任何物体的温度都不能低于 -273.15 摄氏度(热力学中的绝对零)
让我们更新代码以实现此值约束。
上述限制的一个明显解决方案是隐藏属性temperature
(将其设为私有),并定义新的获取器和设置器方法来对其进行操作。 可以按以下步骤完成:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<span class="pl-c"># Making Getters and Setter methods</span> <span class="pl-k">class</span> <span class="pl-v">Celsius</span>: <span class="pl-k">def</span> <span class="pl-en">__init__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">temperature</span><span class="pl-c1">=</span><span class="pl-c1">0</span>): <span class="pl-s1">self</span>.<span class="pl-en">set_temperature</span>(<span class="pl-s1">temperature</span>) <span class="pl-k">def</span> <span class="pl-en">to_fahrenheit</span>(<span class="pl-s1">self</span>): <span class="pl-k">return</span> (<span class="pl-s1">self</span>.<span class="pl-en">get_temperature</span>() <span class="pl-c1">*</span> <span class="pl-c1">1.8</span>) <span class="pl-c1">+</span> <span class="pl-c1">32</span> <span class="pl-c"># getter method</span> <span class="pl-k">def</span> <span class="pl-en">get_temperature</span>(<span class="pl-s1">self</span>): <span class="pl-k">return</span> <span class="pl-s1">self</span>.<span class="pl-s1">_temperature</span> <span class="pl-c"># setter method</span> <span class="pl-k">def</span> <span class="pl-en">set_temperature</span>(<span class="pl-s1">self</span>, <span class="pl-s1">value</span>): <span class="pl-k">if</span> <span class="pl-s1">value</span> <span class="pl-c1"><</span> <span class="pl-c1">-</span><span class="pl-c1">273.15</span>: <span class="pl-k">raise</span> <span class="pl-v">ValueError</span>(<span class="pl-s">"Temperature below -273.15 is not possible."</span>) <span class="pl-s1">self</span>.<span class="pl-s1">_temperature</span> <span class="pl-c1">=</span> <span class="pl-s1">value</span> |
如我们所见,以上方法引入了两个新的get_temperature()
和set_temperature()
方法。
此外,temperature
被替换为_temperature
。 开头的下划线_
用于表示 Python 中的私有变量。
现在,让我们使用以下实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<span class="pl-c"># Making Getters and Setter methods</span> <span class="pl-k">class</span> <span class="pl-v">Celsius</span>: <span class="pl-k">def</span> <span class="pl-en">__init__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">temperature</span><span class="pl-c1">=</span><span class="pl-c1">0</span>): <span class="pl-s1">self</span>.<span class="pl-en">set_temperature</span>(<span class="pl-s1">temperature</span>) <span class="pl-k">def</span> <span class="pl-en">to_fahrenheit</span>(<span class="pl-s1">self</span>): <span class="pl-k">return</span> (<span class="pl-s1">self</span>.<span class="pl-en">get_temperature</span>() <span class="pl-c1">*</span> <span class="pl-c1">1.8</span>) <span class="pl-c1">+</span> <span class="pl-c1">32</span> <span class="pl-c"># getter method</span> <span class="pl-k">def</span> <span class="pl-en">get_temperature</span>(<span class="pl-s1">self</span>): <span class="pl-k">return</span> <span class="pl-s1">self</span>.<span class="pl-s1">_temperature</span> <span class="pl-c"># setter method</span> <span class="pl-k">def</span> <span class="pl-en">set_temperature</span>(<span class="pl-s1">self</span>, <span class="pl-s1">value</span>): <span class="pl-k">if</span> <span class="pl-s1">value</span> <span class="pl-c1"><</span> <span class="pl-c1">-</span><span class="pl-c1">273.15</span>: <span class="pl-k">raise</span> <span class="pl-v">ValueError</span>(<span class="pl-s">"Temperature below -273.15 is not possible."</span>) <span class="pl-s1">self</span>.<span class="pl-s1">_temperature</span> <span class="pl-c1">=</span> <span class="pl-s1">value</span> <span class="pl-c"># Create a new object, set_temperature() internally called by __init__</span> <span class="pl-s1">human</span> <span class="pl-c1">=</span> <span class="pl-v">Celsius</span>(<span class="pl-c1">37</span>) <span class="pl-c"># Get the temperature attribute via a getter</span> <span class="pl-en">print</span>(<span class="pl-s1">human</span>.<span class="pl-en">get_temperature</span>()) <span class="pl-c"># Get the to_fahrenheit method, get_temperature() called by the method itself</span> <span class="pl-en">print</span>(<span class="pl-s1">human</span>.<span class="pl-en">to_fahrenheit</span>()) <span class="pl-c"># new constraint implementation</span> <span class="pl-s1">human</span>.<span class="pl-en">set_temperature</span>(<span class="pl-c1">-</span><span class="pl-c1">300</span>) <span class="pl-c"># Get the to_fahreheit method</span> <span class="pl-en">print</span>(<span class="pl-s1">human</span>.<span class="pl-en">to_fahrenheit</span>()) |
输出:
1 2 3 4 5 6 |
<span class="pl-c1">37</span> <span class="pl-c1">98.60000000000001</span> <span class="pl-v">Traceback</span> (<span class="pl-s1">most</span> <span class="pl-s1">recent</span> <span class="pl-s1">call</span> <span class="pl-s1">last</span>): <span class="pl-v">File</span> <span class="pl-s">"<string>"</span>, <span class="pl-s1">line</span> <span class="pl-c1">30</span>, <span class="pl-s1">in</span> <span class="pl-c1"><</span><span class="pl-s1">module</span><span class="pl-c1">></span> <span class="pl-v">File</span> <span class="pl-s">"<string>"</span>, <span class="pl-s1">line</span> <span class="pl-c1">16</span>, <span class="pl-s1">in</span> <span class="pl-s1">set_temperature</span> <span class="pl-v">ValueError</span>: <span class="pl-v">Temperature</span> <span class="pl-s1">below</span> <span class="pl-c1">-</span><span class="pl-c1">273.15</span> <span class="pl-c1">is</span> <span class="pl-c1">not</span> <span class="pl-s1">possible</span>. |
此更新成功实现了新限制。 我们不再被允许将温度设置为低于-273.15 摄氏度。
注意:私有变量实际上在 Python 中不存在。 只需遵循一些规范。 语言本身没有任何限制。
1 2 3 |
<span class="pl-c1">>></span><span class="pl-c1">></span> <span class="pl-s1">human</span>.<span class="pl-s1">_temperature</span> <span class="pl-c1">=</span> <span class="pl-c1">-</span><span class="pl-c1">300</span> <span class="pl-c1">>></span><span class="pl-c1">></span> <span class="pl-s1">human</span>.<span class="pl-en">get_temperature</span>() <span class="pl-c1">-</span><span class="pl-c1">300</span> |
但是,上述更新的更大问题是,实现我们上一类的所有程序都必须将其代码从obj.temperature
修改为obj.get_temperature()
,并将所有表达式从obj.temperature = val
修改为obj.set_temperature(val)
。
在处理成千上万行代码时,这种重构可能会引起问题。
总而言之,我们的新更新不向后兼容。 这是@property
抢救的地方。
属性类
解决上述问题的一种 Python 方法是使用property
类。 这是我们如何更新代码的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<span class="pl-c"># using property class</span> <span class="pl-k">class</span> <span class="pl-v">Celsius</span>: <span class="pl-k">def</span> <span class="pl-en">__init__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">temperature</span><span class="pl-c1">=</span><span class="pl-c1">0</span>): <span class="pl-s1">self</span>.<span class="pl-s1">temperature</span> <span class="pl-c1">=</span> <span class="pl-s1">temperature</span> <span class="pl-k">def</span> <span class="pl-en">to_fahrenheit</span>(<span class="pl-s1">self</span>): <span class="pl-k">return</span> (<span class="pl-s1">self</span>.<span class="pl-s1">temperature</span> <span class="pl-c1">*</span> <span class="pl-c1">1.8</span>) <span class="pl-c1">+</span> <span class="pl-c1">32</span> <span class="pl-c"># getter</span> <span class="pl-k">def</span> <span class="pl-en">get_temperature</span>(<span class="pl-s1">self</span>): <span class="pl-en">print</span>(<span class="pl-s">"Getting value..."</span>) <span class="pl-k">return</span> <span class="pl-s1">self</span>.<span class="pl-s1">_temperature</span> <span class="pl-c"># setter</span> <span class="pl-k">def</span> <span class="pl-en">set_temperature</span>(<span class="pl-s1">self</span>, <span class="pl-s1">value</span>): <span class="pl-en">print</span>(<span class="pl-s">"Setting value..."</span>) <span class="pl-k">if</span> <span class="pl-s1">value</span> <span class="pl-c1"><</span> <span class="pl-c1">-</span><span class="pl-c1">273.15</span>: <span class="pl-k">raise</span> <span class="pl-v">ValueError</span>(<span class="pl-s">"Temperature below -273.15 is not possible"</span>) <span class="pl-s1">self</span>.<span class="pl-s1">_temperature</span> <span class="pl-c1">=</span> <span class="pl-s1">value</span> <span class="pl-c"># creating a property object</span> <span class="pl-s1">temperature</span> <span class="pl-c1">=</span> <span class="pl-en">property</span>(<span class="pl-s1">get_temperature</span>, <span class="pl-s1">set_temperature</span>) |
我们在get_temperature()
和set_temperature()
内部添加了print()
函数,以清楚地观察它们正在执行。
代码的最后一行创建一个属性对象temperature
。 简而言之,属性将一些代码(get_temperature
和set_temperature
)附加到成员属性访问(temperature
)。
让我们使用以下更新代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<span class="pl-c"># using property class</span> <span class="pl-k">class</span> <span class="pl-v">Celsius</span>: <span class="pl-k">def</span> <span class="pl-en">__init__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">temperature</span><span class="pl-c1">=</span><span class="pl-c1">0</span>): <span class="pl-s1">self</span>.<span class="pl-s1">temperature</span> <span class="pl-c1">=</span> <span class="pl-s1">temperature</span> <span class="pl-k">def</span> <span class="pl-en">to_fahrenheit</span>(<span class="pl-s1">self</span>): <span class="pl-k">return</span> (<span class="pl-s1">self</span>.<span class="pl-s1">temperature</span> <span class="pl-c1">*</span> <span class="pl-c1">1.8</span>) <span class="pl-c1">+</span> <span class="pl-c1">32</span> <span class="pl-c"># getter</span> <span class="pl-k">def</span> <span class="pl-en">get_temperature</span>(<span class="pl-s1">self</span>): <span class="pl-en">print</span>(<span class="pl-s">"Getting value..."</span>) <span class="pl-k">return</span> <span class="pl-s1">self</span>.<span class="pl-s1">_temperature</span> <span class="pl-c"># setter</span> <span class="pl-k">def</span> <span class="pl-en">set_temperature</span>(<span class="pl-s1">self</span>, <span class="pl-s1">value</span>): <span class="pl-en">print</span>(<span class="pl-s">"Setting value..."</span>) <span class="pl-k">if</span> <span class="pl-s1">value</span> <span class="pl-c1"><</span> <span class="pl-c1">-</span><span class="pl-c1">273.15</span>: <span class="pl-k">raise</span> <span class="pl-v">ValueError</span>(<span class="pl-s">"Temperature below -273.15 is not possible"</span>) <span class="pl-s1">self</span>.<span class="pl-s1">_temperature</span> <span class="pl-c1">=</span> <span class="pl-s1">value</span> <span class="pl-c"># creating a property object</span> <span class="pl-s1">temperature</span> <span class="pl-c1">=</span> <span class="pl-en">property</span>(<span class="pl-s1">get_temperature</span>, <span class="pl-s1">set_temperature</span>) <span class="pl-s1">human</span> <span class="pl-c1">=</span> <span class="pl-v">Celsius</span>(<span class="pl-c1">37</span>) <span class="pl-en">print</span>(<span class="pl-s1">human</span>.<span class="pl-s1">temperature</span>) <span class="pl-en">print</span>(<span class="pl-s1">human</span>.<span class="pl-en">to_fahrenheit</span>()) <span class="pl-s1">human</span>.<span class="pl-s1">temperature</span> <span class="pl-c1">=</span> <span class="pl-c1">-</span><span class="pl-c1">300</span> |
输出:
1 2 3 4 5 6 7 8 9 10 |
<span class="pl-v">Setting</span> <span class="pl-s1">value</span>... <span class="pl-v">Getting</span> <span class="pl-s1">value</span>... <span class="pl-c1">37</span> <span class="pl-v">Getting</span> <span class="pl-s1">value</span>... <span class="pl-c1">98.60000000000001</span> <span class="pl-v">Setting</span> <span class="pl-s1">value</span>... <span class="pl-v">Traceback</span> (<span class="pl-s1">most</span> <span class="pl-s1">recent</span> <span class="pl-s1">call</span> <span class="pl-s1">last</span>): <span class="pl-v">File</span> <span class="pl-s">"<string>"</span>, <span class="pl-s1">line</span> <span class="pl-c1">31</span>, <span class="pl-s1">in</span> <span class="pl-c1"><</span><span class="pl-s1">module</span><span class="pl-c1">></span> <span class="pl-v">File</span> <span class="pl-s">"<string>"</span>, <span class="pl-s1">line</span> <span class="pl-c1">18</span>, <span class="pl-s1">in</span> <span class="pl-s1">set_temperature</span> <span class="pl-v">ValueError</span>: <span class="pl-v">Temperature</span> <span class="pl-s1">below</span> <span class="pl-c1">-</span><span class="pl-c1">273</span> <span class="pl-c1">is</span> <span class="pl-c1">not</span> <span class="pl-s1">possible</span> |
如我们所见,任何检索temperature
值的代码都会自动调用get_temperature()
,而不是字典(dict)查找。 类似地,任何为temperature
赋值的代码都会自动调用set_temperature()
。
我们甚至可以在上面看到即使创建对象时也调用了set_temperature()
。
1 2 |
<span class="pl-c1">>></span><span class="pl-c1">></span> <span class="pl-s1">human</span> <span class="pl-c1">=</span> <span class="pl-v">Celsius</span>(<span class="pl-c1">37</span>) <span class="pl-v">Setting</span> <span class="pl-s1">value</span>... |
你能猜出为什么吗?
原因是在创建对象时,将调用__init__()
方法。 该方法具有行self.temperature = temperature
。 该表达式自动调用set_temperature()
。
同样,任何访问c.temperature
都会自动调用get_temperature()
。 这就是财产的作用。 这里还有一些例子。
1 2 3 4 5 6 7 8 9 |
<span class="pl-c1">>></span><span class="pl-c1">></span> <span class="pl-s1">human</span>.<span class="pl-s1">temperature</span> <span class="pl-v">Getting</span> <span class="pl-s1">value</span> <span class="pl-c1">37</span> <span class="pl-c1">>></span><span class="pl-c1">></span> <span class="pl-s1">human</span>.<span class="pl-s1">temperature</span> <span class="pl-c1">=</span> <span class="pl-c1">37</span> <span class="pl-v">Setting</span> <span class="pl-s1">value</span> <span class="pl-c1">>></span><span class="pl-c1">></span> <span class="pl-s1">c</span>.<span class="pl-en">to_fahrenheit</span>() <span class="pl-v">Getting</span> <span class="pl-s1">value</span> <span class="pl-c1">98.60000000000001</span> |
通过使用property
,我们可以看到在实现值约束时不需要修改。 因此,我们的实现是向后兼容的。
注意:实际温度值存储在私有_temperature
变量中。temperature
属性是为该私有变量提供接口的属性对象。
@property
装饰器
在 Python 中,property()
是一个内置函数,可创建并返回property
对象。 该函数的语法为:
1 |
<span class="pl-en">property</span>(<span class="pl-s1">fget</span><span class="pl-c1">=</span><span class="pl-c1">None</span>, <span class="pl-s1">fset</span><span class="pl-c1">=</span><span class="pl-c1">None</span>, <span class="pl-s1">fdel</span><span class="pl-c1">=</span><span class="pl-c1">None</span>, <span class="pl-s1">doc</span><span class="pl-c1">=</span><span class="pl-c1">None</span>) |
哪里,
fget
是获取属性值的函数fset
是设置属性值的函数fdel
是删除属性的函数doc
是一个字符串(如注释)
从实现中可以看出,这些函数参数是可选的。 因此,可以简单地如下创建属性对象。
1 2 |
<span class="pl-c1">>></span><span class="pl-c1">></span> <span class="pl-en">property</span>() <span class="pl-c1"><</span><span class="pl-s1">property</span> <span class="pl-s1">object</span> <span class="pl-s1">at</span> <span class="pl-c1">0x0000000003239B38</span><span class="pl-c1">></span> |
属性对象具有getter()
,setter()
和deleter()
三种方法,以便在以后指定fget
,fset
和fdel
。 这意味着,该行:
1 |
<span class="pl-s1">temperature</span> <span class="pl-c1">=</span> <span class="pl-en">property</span>(<span class="pl-s1">get_temperature</span>,<span class="pl-s1">set_temperature</span>) |
可以细分为:
1 2 3 4 5 6 |
<span class="pl-c"># make empty property</span> <span class="pl-s1">temperature</span> <span class="pl-c1">=</span> <span class="pl-en">property</span>() <span class="pl-c"># assign fget</span> <span class="pl-s1">temperature</span> <span class="pl-c1">=</span> <span class="pl-s1">temperature</span>.<span class="pl-en">getter</span>(<span class="pl-s1">get_temperature</span>) <span class="pl-c"># assign fset</span> <span class="pl-s1">temperature</span> <span class="pl-c1">=</span> <span class="pl-s1">temperature</span>.<span class="pl-en">setter</span>(<span class="pl-s1">set_temperature</span>) |
这两段代码是等效的。
熟悉 Python 装饰器的程序员可以认识到上述构造可以实现为装饰器。
我们甚至无法定义名称get_temperature
和set_temperature
,因为它们是不必要的,并污染了类名称空间。
为此,我们在定义获取器和设置器函数的同时重用temperature
名称。 让我们看一下如何将其实现为装饰器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<span class="pl-c"># Using @property decorator</span> <span class="pl-k">class</span> <span class="pl-v">Celsius</span>: <span class="pl-k">def</span> <span class="pl-en">__init__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">temperature</span><span class="pl-c1">=</span><span class="pl-c1">0</span>): <span class="pl-s1">self</span>.<span class="pl-s1">temperature</span> <span class="pl-c1">=</span> <span class="pl-s1">temperature</span> <span class="pl-k">def</span> <span class="pl-en">to_fahrenheit</span>(<span class="pl-s1">self</span>): <span class="pl-k">return</span> (<span class="pl-s1">self</span>.<span class="pl-s1">temperature</span> <span class="pl-c1">*</span> <span class="pl-c1">1.8</span>) <span class="pl-c1">+</span> <span class="pl-c1">32</span> <span class="pl-en">@<span class="pl-s1">property</span></span> <span class="pl-k">def</span> <span class="pl-en">temperature</span>(<span class="pl-s1">self</span>): <span class="pl-en">print</span>(<span class="pl-s">"Getting value..."</span>) <span class="pl-k">return</span> <span class="pl-s1">self</span>.<span class="pl-s1">_temperature</span> <span class="pl-en">@<span class="pl-s1">temperature</span>.<span class="pl-s1">setter</span></span> <span class="pl-k">def</span> <span class="pl-en">temperature</span>(<span class="pl-s1">self</span>, <span class="pl-s1">value</span>): <span class="pl-en">print</span>(<span class="pl-s">"Setting value..."</span>) <span class="pl-k">if</span> <span class="pl-s1">value</span> <span class="pl-c1"><</span> <span class="pl-c1">-</span><span class="pl-c1">273.15</span>: <span class="pl-k">raise</span> <span class="pl-v">ValueError</span>(<span class="pl-s">"Temperature below -273 is not possible"</span>) <span class="pl-s1">self</span>.<span class="pl-s1">_temperature</span> <span class="pl-c1">=</span> <span class="pl-s1">value</span> <span class="pl-c"># create an object</span> <span class="pl-s1">human</span> <span class="pl-c1">=</span> <span class="pl-v">Celsius</span>(<span class="pl-c1">37</span>) <span class="pl-en">print</span>(<span class="pl-s1">human</span>.<span class="pl-s1">temperature</span>) <span class="pl-en">print</span>(<span class="pl-s1">human</span>.<span class="pl-en">to_fahrenheit</span>()) <span class="pl-s1">coldest_thing</span> <span class="pl-c1">=</span> <span class="pl-v">Celsius</span>(<span class="pl-c1">-</span><span class="pl-c1">300</span>) |
输出:
1 2 3 4 5 6 7 8 9 10 11 |
<span class="pl-v">Setting</span> <span class="pl-s1">value</span>... <span class="pl-v">Getting</span> <span class="pl-s1">value</span>... <span class="pl-c1">37</span> <span class="pl-v">Getting</span> <span class="pl-s1">value</span>... <span class="pl-c1">98.60000000000001</span> <span class="pl-v">Setting</span> <span class="pl-s1">value</span>... <span class="pl-v">Traceback</span> (<span class="pl-s1">most</span> <span class="pl-s1">recent</span> <span class="pl-s1">call</span> <span class="pl-s1">last</span>): <span class="pl-v">File</span> <span class="pl-s">"<string>"</span>, <span class="pl-s1">line</span> <span class="pl-c1">29</span>, <span class="pl-s1">in</span> <span class="pl-c1"><</span><span class="pl-s1">module</span><span class="pl-c1">></span> <span class="pl-v">File</span> <span class="pl-s">"<string>"</span>, <span class="pl-s1">line</span> <span class="pl-c1">4</span>, <span class="pl-s1">in</span> <span class="pl-s1">__init__</span> <span class="pl-v">File</span> <span class="pl-s">"<string>"</span>, <span class="pl-s1">line</span> <span class="pl-c1">18</span>, <span class="pl-s1">in</span> <span class="pl-s1">temperature</span> <span class="pl-v">ValueError</span>: <span class="pl-v">Temperature</span> <span class="pl-s1">below</span> <span class="pl-c1">-</span><span class="pl-c1">273</span> <span class="pl-c1">is</span> <span class="pl-c1">not</span> <span class="pl-s1">possible</span> |
上面的实现是简单而有效的。 建议使用property
的方式。