Python的property - 北极神话的日志 - 网易博客
property( [fget[, fset[, fdel[, doc]]]]) - Return a property attribute for new-style classes (classes that derive from object).
fget is a function for getting an attribute value, likewise fset is a function for setting, and fdel a function for del'ing, an attribute. Typical use is to define a managed attribute x:
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.")If given, doc will be the docstring of the property attribute. Otherwise, the property will copy fget's docstring (if it exists). This makes it possible to create read-only properties easily using property() as a decorator:
class Parrot(object): def __init__(self): self._voltage = 100000 @property def voltage(self): """Get the current voltage.""" return self._voltage
turns the voltage() method into a ``getter'' for a read-only attribute with the same name.
New in version 2.2. Changed in version 2.5: Use fget's docstring if no doc given.
========================================================================================
看 SQLObject的魔法属性时想到了property,复习下python的property
通过这个peroerty你可以定义一个真正的"只读"类,当然这只是property的小功能而已.
记得的好像有点像Delphi,用这个property定义的概念上的属性,用起来跟下面的写法差不多,但是可以比直接写类似于:
class A(object):
a = 1
b = 2
这样的属性获得更灵活的功能和更好的性能(性能是python In a Nutshell上说的)
这是help(property)得来的原型:
property(fget=None, fset=None, fdel=None, doc=None) -> property attribute
先抄一个例子过来:
class Rectangle(object): #注意这里必须以object为基类,否则这个area仍然可以修改而不会报错
def __init__(self,width,height):
self.width = width
self.height = height
def _getArea(self):
return self.width* self.height
# 可以看到这里只给原型中的fget和doc赋了值.
area = property(_getArra,doc='area of the ractangle')
试着运行这个例子,给这个例子赋值:
>>> obj.area=34
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
如此我们就得到了一个只读属性.再来看property的原型:
class C(object):
...
attrib = property(fget=None, fset=None, fdel=None, doc=None)
x = C()
执行x.attrib,则python调用fget指定的函数;
执行x.attrib= value 则调用fset函数;
而del x.attrib 就是调用fdel函数了
doc指定docstring,没啥好说的.
这种用法在MVC 中有个好处,那就是把业务逻辑放到了m中,而不是放到c中,当然,你就要写到c中,也是没有办法的事情.....
看下面这个SQLObject的例子:
在数据库中存有类似 "1+1", "234*234 - 41"这样的运算表达式,你需要实现一个v,让他显示这些个表达式,并在用户输入结果后验证用户的输入是否正确, 你可以写在V中,不过这里我们写在M中,用property:
class Exam(SQLObject):
exercise= UnicodeCol()
def _solve(self):
return eval(self.exercise)
solution = property(fget=_solve)
然后你就可以通过类似如下的语句在访问的时候计算出来结果:
obj = Exam(exercise="1+1")
print "%s = %s" % (obj.exercise,e.solution)
建议是遇到需要诸如getAttrib,setAttrib的时候,尽量使用property,性能好又灵活!何乐而不为呢?