@property是非常好用的装饰器,我们先讲讲Python中的@property的实现了什么功能,再谈谈@property的应用场景。property翻译过来就是属性,它的作用就是把方法method转换为属性property。因此被@property装饰的成员函数,只能有一个参数self;不能和别的类属性同名;并且在调用时不需要加()。
class A():
def __init__(self):
self._value=1
# 注意,这里不能要和value区分,确保不会和property装饰的成员函数同名!
# 如果重名,会陷入死循环
@property
def value(self): # 只能有一个参数self
return self._value
a=A()
print(a.value) # 不用加()
# 输出1
这就是property装饰实现的功能,把方法变成属性。如果只有@property装饰,那么value是只读不可写的。因此在property装饰的基础上,还附赠了@x.setter装饰器和@x.deleter装饰器。
class A():
def __init__(self):
self._value=1
@property
def value(self):
return self._value
@value.setter
def value(self,x)
if x<=0:
raise ValueError('value must > 0')
self._value=x
@value.deleter
def value(self):
del self._value
a=A()
a.value=-1
del a.value # 调用@value.deleter修饰的函数
**在对a.value赋值时,实际上调用的是被@value.setter装饰的函数,**我们可以在该函数进行判断数据类型、数据范围等。至此@property装饰适合下面这些场景:
1.只读不可修改的属性。只需要实现@property
2.输入对setter进行判断。
3.需要实时地计算属性值。
解释一下第三种情况,比如我们已知电阻阻值和电压,要求电流,最好的方式就是实现@property装饰的函数,可以像属性一样访问电流,并且是实时计算的。
class OHM():
def __init__(self):
self._U=1
self._R=1
@property
def I(self):
return self._U/self._R
@property
def R(self):
return self._R
@R.setter
def R(self,r):
if r<=0:
raise ValueError('r must >0')
self._R=r
ohm=OHM()
ohm.R=1
print(ohm.I)
版权声明:本文为fengchi863原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。