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方法。

posted on 2018-03-06 12:00  nicolas_Z  阅读(126)  评论(0)    收藏  举报

导航