Python Propety

Python 2.6版本中,添加了一种新的类成员函数的访问方式property

原型

1
2
3
4
5
6
7
8
class property([fget[, fset[, fdel[, doc]]]])
fget:获取属性

fset:设置属性

fdel:删除属性

doc:属性含义

用法

让成员函数通过属性方式调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class C(object):
def __init__(self):
self._x = None
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.")
a = C()
print C.x.__doc__ #打印doc
print a.x #调用a.getx()

a.x = 100 #调用a.setx()
print a.x

try:
del a.x #调用a.delx()
print a.x #已被删除,报错
except Exception, e:
print e

输出结果:

1
2
3
4
I'm the 'x' property.
None
100
'C' object has no attribute '_x'

利用property装饰器,让成员函数称为只读的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Parrot(object):
def __init__(self):
self._voltage = 100000

@property
def voltage(self):
"""Get the current voltage."""
return self._voltage

a = Parrot()
print a.voltage #通过属性调用voltage函数
try:
print a.voltage() #不允许调用函数,为只读的
except Exception as e:
print e

输出结果:

1
2
100000
'int' object is not callable

利用property装饰器实现property函数的功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class C(object):
def __init__(self):
self._x = None

@property
def x(self):
"""I'm the 'x' property."""
return self._x

@x.setter
def x(self, value):
self._x = value

@x.deleter
def x(self):
del self._x

其他应用

bottle源码中的应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Request(threading.local):
""" Represents a single request using thread-local namespace. """
...

@property
def method(self):
''' Returns the request method (GET,POST,PUT,DELETE,...) '''
return self._environ.get('REQUEST_METHOD', 'GET').upper()

@property
def query_string(self):
''' Content of QUERY_STRING '''
return self._environ.get('QUERY_STRING', '')

@property
def input_length(self):
''' Content of CONTENT_LENGTH '''
try:
return int(self._environ.get('CONTENT_LENGTH', '0'))
except ValueError:
return 0

@property
def COOKIES(self):
"""Returns a dict with COOKIES."""
if self._COOKIES is None:
raw_dict = Cookie.SimpleCookie(self._environ.get('HTTP_COOKIE',''))
self._COOKIES = {}
for cookie in raw_dict.values():
self._COOKIES[cookie.key] = cookie.value
return self._COOKIES

在django model中的应用,实现连表查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from django.db import models

class Person(models.Model):
name = models.CharField(max_length=30)
tel = models.CharField(max_length=30)

class Score(models.Model):
pid = models.IntegerField()
score = models.IntegerField()

def get_person_name():
return Person.objects.get(id=pid)

name = property(get_person_name) #name称为Score表的属性,通过与Person表联合查询获取name