Python学习之路(21)——@property
Python中有一个被称为 属性函数(property)的概念,作用是返回一个property属性,其语法格式如下:
class property(fget = None, fset = None, fdel = None, doc = None)
fget是获取属性值的函数。
fset是用于设置属性值的功能。
fdel是用于删除属性值的功能。
并且doc为属性创建一个docstring。
典型的用法是定义一个托管属性x。
class C:
def __init__(self):
self._x = 10
def getx(self):
print("---getx---")
return self._x
def setx(self, value):
print("---setx---")
self._x = value
def delx(self):
print("---delx---")
del self._x
x = property(getx, setx, delx, "I'm the 'x' property")
if __name__ == '__main__':
c = C()
print(c.x)
c.x = 100
print(c.x)
del c.x
c是C的实例,则c.x将会调用getter,c.x = vaule将会调用setter, del c.x将会调用deleter。
上述代码的执行结果如下:
---getx--- 10 ---setx--- ---getx--- 100 ---delx---
另外还可以将属性函数作为一个方法的装饰器来使用。这样可以将一个类方法转变成一个类属性。
下例是一个只读属性的例子:
class Person:
def __init__(self, first_name, last_name):
'''
constructor function
:param first_name:
:param last_name:
'''
self.first_name = first_name
self.last_name = last_name
@property
def full_name(self):
'''
Return the full name
'''
print("---full_name---")
return "%s %s" % (self.first_name, self.last_name)
上面的代码,我们创建了两个类属性self.first_name和self.last_name。接着创建了一个类方法full_name,这个类方法有一个@property装饰器。
>>> p = Person("nicolas", "923")
>>> p.full_name()
---full_name---
Traceback (most recent call last):
File "<pyshell#31>", line 1, in <module>
p.full_name()
TypeError: 'str' object is not callable
>>>
>>> p.full_name
---full_name---
'nicolas 923'
>>>
>>> p.first_name
'nicolas'
>>> p.last_name
'923'
>>>
>>> p.full_name = "923", "nicolas"
Traceback (most recent call last):
File "<pyshell#29>", line 1, in <module>
p.full_name = "923", "nicolas"
AttributeError: can't set attribute
>>>
可以看到,方法变成了属性,如果使用调用方法的方式,就会抛出异常,而使用调用属性的方式,就能正确访问。最后如果我们试图将该属性设置为其他值,会引发一个AttributeError异常。(因为@property装饰器将full_name()方法转换成为具有相同名称的只读属性"getter",并设置为full_name的文档字符串为"Return the full name"。)
Property对象具有可用作装饰器的getter、setter和deleter方法,用于创建property副本,并将相应的访问器函数设置为装饰的功能。如下例:
>>> class C:
def __init__(self):
self._x = 10000
@property
def x(self):
''' I'm the "x" property. '''
return self._x
@x.setter
def x(self, value):
print("---x.setter---")
self._x = value
@x.deleter
def x(self):
print("---x.deleter---")
del self._x
>>> c = C()
>>> c.x
10000
>>> c.x =20000
---x.setter---
>>> c.x
20000
>>> del c.x
---x.deleter---
>>> c.x
Traceback (most recent call last):
File "<pyshell#63>", line 1, in <module>
c.x
File "<pyshell#57>", line 7, in x
return self._x
AttributeError: 'C' object has no attribute '_x'
上面的代码演示了如何为x属性创建getter、setter和deleter方法。
使用一个名为@x.setter的装饰器装饰第二个方法也为x的方法来实现创建setter方法,同样@x.deleter实现deleter方法。
浙公网安备 33010602011771号