我试图填补我对蟒蛇property()
的理解中的空白。
以下是我提出的代码,以了解property()
:
class Temperature:
def __init__(self, temp = 10):
self.set_temp(temp)
def to_farenheit(self):
return (self._temp * 1.8) + 32
def get_temp(self):
print "getting temperature value"
return self._temp
def set_temp(self, temp):
print "setting temperature value"
if temp < -237:
raise ValueError("this shud be above -273")
else:
self._temp = temp
temps = property(get_temp, set_temp)
我执行上面的类并执行以下操作:
>>> t = Temperature()
setting temperature value
>>> t.temps
getting temperature value
10
>>> t.temps = 13
>>> t.temps
13
>>> t.get_temp()
getting temperature value
10
>>>
正如您在上面所看到的,当我尝试通过分配temp
设置t.temps = 13
值时,set_temp()
函数未被调用,因为{{1功能。另外,我最终得到了变量property()
我错过了什么?
答案 0 :(得分:8)
这只是因为你使用Python 2而忘记了object
的子类。在你的情况下property
根本不起作用,因为它是一个旧式的类。
最好将子类object
:
class Temperature(object):
...
甚至更好:使用Python 3. Python 3不再具有旧式类,您可以省略(object)
部分,因为它是隐含的。
但是,当您可以使用装饰器语法时,您真的不应该定义get_temp
或set_temp
函数。你肯定不应该直接打电话给他们。
这将更加pythonic:
class Temperature(object):
def __init__(self, temp = 10):
self.temps = temp
def to_farenheit(self):
return (self._temp * 1.8) + 32
@property
def temps(self):
print("getting temperature value")
return self._temp
@temps.setter
def temps(self, temp):
print("setting temperature value")
if temp < -237:
raise ValueError("this shud be above -273")
else:
self._temp = temp
该示例适用于Python 2 和 Python 3。
答案 1 :(得分:1)
此问题仅发生在python 2中。
来自the docs:
class property([fget [,fset [,fdel [,doc]]]])
为新式类(从对象派生的类)返回属性属性。
(强调我的。)
如果通过继承Temperature
使object
成为新式类,则该属性将按预期工作。
答案 2 :(得分:1)
使用利用new-style classes的descriptors for properties。
class Temperature(object):
def __init__(self, temp=10):
self.temps = temp
def to_farenheit(self):
return (self._temp * 1.8) + 32
def get_temp(self):
print "getting temperature value"
return self._temp
def set_temp(self, temp):
print "setting temperature value"
if temp < -237:
raise ValueError("this shud be above -273")
else:
self._temp = temp
temps = property(get_temp, set_temp)
这为您提供了“正确”的行为。
In [30]: t = Temperature()
setting temperature value
In [31]: t.temps
getting temperature value
Out[31]: 10
In [32]: t.temps = 100
setting temperature value
In [33]: t.temps
getting temperature value
Out[33]: 100
In [34]: t.__dict__
Out[34]: {'_temp': 100}