浙江省高等学校教师教育理论培训

微信搜索“教师资格证岗前培训”小程序

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Python的property - 北极神话的日志 - 网易博客

Python的property   

2008-02-23 21:41:08|  分类: python |  标签:  |字号  订阅

 

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,性能好又灵活!何乐而不为呢?

posted on 2012-11-27 10:06  lexus  阅读(427)  评论(0编辑  收藏  举报