python的property内置函数,把特定属性访问定位到get和set处理器函数,也叫做特性(Property)。
特性协议把一个特定属性的访问、设置、删除操作指向入参提供的方法,这样能够在属性访问、设置、删除时添加自动运行的代码,还可以为属性提供文档。
通过内置函数property创建特性并将其分配给类属性,可以被子类和实例继承。
一个特性管理一个单个的、特定的属性。
使用特性可以像访问属性一样调用方法。
把property()内置函数的结果赋值给一个类属性来创建一个特性。
用法
property(fget=None, fset=None, fdel=None, doc=None)
#比如:
class C(object):
def __init__(self,x):self._x = x
def getx(self): return self._x
def setx(self, value): self._x = value
def delx(self): del self._x
x = property(getx, setx, delx, "I'm the 'x' property.")
描述
fget:获取属性值的函数
fset:设置属性值的函数
fdel:删除属性值的函数
doc:属性描述信息
注意:getx里面的self._x不能用self.x,因为self.x会自动调用getx,导致陷入无限循环。
访问属性时自动调用fget函数,比如C().x自动调用getx()
设置属性时自动调用fset函数,比如C().x=v自动调用setx(v)
删除属性时自动调用fdel函数,比如del C().x自动调用delx()
获取属性描述时自动获取doc的值,比如C.name.doc
示例
>>> class Person:
def __init__(self,name):
self._name=name
def getName(self):
print('获取属性值')
return self._name
def setName(self,value):
print('设置属性值')
self._name=value
def delName(self):
print('删除属性')
del self._name
name = property(getName,setName,delName,'属性描述信息')
>>> class PTPerson(Person):pass
>>> p1=PTPerson('梯阅线条')
# p1.name 访问属性name时,自动调用getName(fget)函数
>>> p1.name
获取属性值
'梯阅线条'
# p1.name=值 设置属性name时,自动调用setName(fset)函数
>>> p1.name='梯阅'
设置属性值
>>> p1.name
获取属性值
'梯阅'
# del p1.name 删除属性name时,自动调用delName(fdel)函数
>>> del p1.name
删除属性
>>> p1.name='梯阅线条'
设置属性值
>>> p1.name
获取属性值
'梯阅线条'
# PTPerson.name.__doc__ 获取属性描述时,自动获取doc的值
>>> PTPerson.name.__doc__
'属性描述信息'
函数装饰器:
@decorator
def func(args):pass
等效于
def func(args):pass
func=decorator(func)
用法
class ClassName:
# attribute=property(attribute),通过特性property创建属性
@property
def attribute(self):
'attribute doc' # 属性描述,赋值给property()的doc入参
return self._attribute
# attribute=attribute.setter(attribute)
@attribute.setter
def attribute(self, value):
self._attribute = value
# attribute=attribute.deleter(attribute)
@attribute.deleter
def attribute(self):
del self._attribute
描述
(1) 获取属性值时自动调用@property修饰的attribute()方法;
(2) 设置属性值时自动调用@attribute.setter修饰的attribute()方法;
(3) 删除属性时自动调用@attribute.deleterr修饰的attribute()方法;
(4) 创建(获取)属性用@property;
(5) 设置属性值用@属性名.setter;
(6) 删除属性用@属性名.deleter;
(7) @property装饰的方法用于创建属性,被装饰的方法名为属性名;
(8) @property创建的属性,必须返回一个值,否则无法访问该属性;
(9) @attribute.setter、@attribute.deleter的attribute必须和@property装饰的方法名attribute一致;即setter和deleter装饰器前面的attribute和@property装饰的方法名必须一致;用于区分多个属性,指明设置和修改哪个属性;
(10) @ attribute.setter和@ attribute.deleter装饰的方法名必须和和@property装饰的方法名一致;
(11) 设置、删除属性前必须先用property创建属性,否则报错;
示例
>>> class PTCircle:
def __init__(self,r):
self.pi=3.14
self._r=r
self._d=0
self._c=0
self._s=0
@property
def r(self):
'doc:定义半径'
print('获取半径')
return self._r
#setter前面的r必须与@property 修饰的方法名r一致
#@r.setter装饰的方法名r必须与@property 修饰的方法名r一致
@r.setter
def r(self,value):
print('设置半径')
if value<0:
raise ValueError('半径不能小于0')
self._r=value
#deleter前面的r必须与@property 修饰的方法名r一致
#@r.deleter装饰的方法名r必须与@property 修饰的方法名r一致
@r.deleter
def r(self):
print('删除半径')
del self._r
@property
def c(self):
print('获取周长')
self._c=2*self.pi*self._r
return self._c
@property
def s(self):
print('获取面积')
self._s=self.pi*(self._r**2)
return self._s
# @c.setter装饰的方法名sc与@property 修饰的方法名c不一致,报错
@c.setter
def sc(self,value):
print('设置周长')
self._c=value
# @c.deleter装饰的方法名dc与@property 修饰的方法名c不一致,报错
@c.deleter
def dc(self,value):
print('删除周长')
del self._c
#@property创建的属性,必须返回一个值,否则无法访问该属性
@property
def d(self):
'doc:定义直径'
print('获取直径')
self._d=2*self._r
>>> c1=PTCircle(2)
>>> c1.r
获取半径
2
>>> del c1.r
删除半径
>>> c1.r=3
设置半径
>>> c1.r
获取半径
3
>>> c1.c
获取周长
18.84
>>> c1.s
获取面积
28.26
>>> PTCircle.r.__doc__
'doc:定义半径'
>>> c1.c=1
Traceback (most recent call last):
File "<pyshell#171>", line 1, in <module>
c1.c=1
AttributeError: can't set attribute
>>> del c1.c
Traceback (most recent call last):
File "<pyshell#172>", line 1, in <module>
del c1.c
AttributeError: can't delete attribute
#@property创建的属性,必须返回一个值,否则无法访问该属性
#没有返回直径的值
>>> c1.d
获取直径