python中的@propertity

这个上面对装饰器的讨论还是不错的:http://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do?rq=1


假设定义了一个类:C,该类必须继承自object类,有一私有变量_x 

class C: 
 def __init__(self): 
  self.__x=None 
  1.现在介绍第一种使用属性的方法: 
  在该类中定义三个函数,分别用作赋值、取值和删除变量(此处表达也许不很清晰,请看示例) 
 def getx(self): 
  return self.__x 
 def setx(self,value): 
  self.__x=value 
 def delx(self): 
  del self.__x 
 x=property(getx,setx,delx,'') 


property函数原型为property(fget=None,fset=None,fdel=None,doc=None),所以根据自己需要定义相应的函数即可。 

  现在这个类中的x属性便已经定义好了,我们可以先定义一个C的实例c=C(),然后赋值c.x=100,取值y=c.x,删除:del c.x。是不是很简单呢?请看第二种方法 


  2.下面看第二种方法(在2.6中新增) 
  首先定义一个类C: 

 同一属性的三个函数名要相同哦。 

转自:http://joy2everyone.iteye.com/blog/910950 
@property 可以将python定义的函数“当做”属性访问,从而提供更加友好访问方式,但是有时候setter/getter也是需要的,我们视具体情况吧 

请注意以下代码场景: 

代码片段1: 
Python2.6代码  
class Parrot(object):  
    def __init__(self):  
        self._voltage = 100000  
  
    @property  
    def voltage(self):  
        """Get the current voltage."""  
        return self._voltage  
  
if __name__ == "__main__":  
    # instance  
    p = Parrot()  
    # similarly invoke "getter" via @property  
    print p.voltage  
    # update, similarly invoke "setter"  
    p.voltage = 12  




代码片段2: 
Python2.6代码  
class Parrot:  
    def __init__(self):  
        self._voltage = 100000  
  
    @property  
    def voltage(self):  
        """Get the current voltage."""  
        return self._voltage  
  
if __name__ == "__main__":  
    # instance  
    p = Parrot()  
    # similarly invoke "getter" via @property  
    print p.voltage  
    # update, similarly invoke "setter"  
    p.voltage = 12  




代码1、2的区别在于 
class Parrot(object): 

在python2.6下,分别运行测试 
片段1:将会提示一个预期的错误信息 AttributeError: can't set attribute 
片段2:正确运行 

参考python2.6文档,@property将提供一个ready-only property,以上代码没有提供对应的@voltage.setter,按理说片段2代码将提示运行错误,在python2.6文档中,我们可以找到以下信息: 

BIF: 
property([fget[, fset[, fdel[, doc]]]]) 
Return a property attribute for new-style classes (classes that derive from object). 
原来在python2.6下,内置类型 object 并不是默认的基类,如果在定义类时,没有明确说明的话(代码片段2),我们定义的Parrot(代码片段2)将不会继承object 

而object类正好提供了我们需要的@property功能,在文档中我们可以查到如下信息: 

new-style class 
Any class which inherits from object. This includes all built-in types like list and dict. Only new-style classes can use Python's newer, versatile features like __slots__, descriptors, properties, and __getattribute__(). 

同时我们也可以通过以下方法来验证 
Python 2.6代码  
class A:  
    pass  

>>type(A) 
<type 'classobj'> 
Python 2.6代码  
class A(object):  
    pass  

>>type(A) 
<type 'type'> 



从返回的<type 'classobj'>,<type 'type'>可以看出<type 'type'>是我们需要的object类型(python 3.0 将object类作为默认基类,所以都将返回<type 'type'>) 

为了考虑代码的python 版本过渡期的兼容性问题,我觉得应该定义class文件的时候,都应该显式定义object,做为一个好习惯 

最后的代码将如下: 
Python代码  
class Parrot(object):  
    def __init__(self):  
        self._voltage = 100000  

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

    @voltage.setter  
    def voltage(self, new_value):  
        self._voltage = new_value  
  
if __name__ == "__main__":  
    # instance  
    p = Parrot()  
    # similarly invoke "getter" via @property  
    print p.voltage  
    # update, similarly invoke "setter"  
    p.voltage = 12  




另外,@property是在2.6、3.0新增的,2.5没有该功能。
原文地址:https://www.cnblogs.com/double12gzh/p/10166143.html