可以有3种方式,:
x=property(getter,setter, deleter)的方式。
property函数原型为property(fget=None,fset=None,fdel=None,doc=None),所以根据自己需要定义相应的函数即可。
@property,@x.setter,@x.deleter的方式。
__get__, __set__, __delete__的方式。
使用property()的例子:
class C(object): y = 3 z = 4 def __init__(self): self.__x = 2 def getx(self): return self.__x def setx(self, val): print "x is read only" x = property(getx, setx) #这不是真正的只读属性, 虽然在setx中,没有更新__x, 但你仍可对x属性赋值, 虽然复制不生效, 但也不报错 x = property(getx) #这是真正的只读属性, 不给属性增加setter, 这是真正的只读属性, 因为一旦要给x赋值的时候, 运行就报错 x = property(lambda self: self.__x)#这是真正的只读属性, 因为一旦要给x赋值的时候, 运行就报错 c=C() print(c.x,c.y,c.z) c.x=3 print(c.x,c.y,c.z)
使用@property的例子:
class B(object): def __init__(self): self._x = None @property def x(self): #这是x的getter """I'm the 'x' property.""" return self._x @x.setter def x(self, value): #这是x的setter self._x = value @x.deleter def x(self): #这是x的deleter del self._x b=B() b.x=12 print(b.x)
使用__get__, __set__, __delete__的例子:
这种方法把每个属性做了一个类。
#!/usr/bin/env python class Celsius(object): def __init__(self, value=0.0): self.value = float(value) def __get__(self, instance, owner): return self.value def __set__(self, instance, value): self.value = float(value) class Farenheit(object): def __get__(self, instances, owner): return instances.celsius * 9/5 + 32 def __set__(self, instances, value): instances.celsius = (float(value) - 32) * 5/9 class Temperature(object): celsius = Celsius() farenheit = Farenheit() oven= Temperature() oven.farenheit=450 print oven.celsius # 232.222222222 oven.celsius = 175 print oven.farenheit # 347.0
descriptor简单来看就是把对属性的访问,通过一个descriptor class来间接访问。
这个class可以有__get__, __set__, __delete__这些方法来实现属性的读,写,删除。
我们可以把相关的属性值放在descriptor class里面,比如上面例子里的class Celsius,用self.value来 保存属性值。
也可以放在descriptor class owner里面,所谓owner,就是使用descriptor class的类,就像Temperature。 例子中的class Farenheit,本身没有保存属性值,而是使用class Temperature的属性(celsius)。对于这种情况, 需要用到__get__, __set__中的第二个参数(instance)。
对比一下:
#!/usr/bin/env python class Temperature( object ): def fget( self ): return self.celsius * 9 / 5 + 32 def fset( self, value ): self.celsius= (float(value)-32) * 5 / 9 farenheit= property( fget, fset ) def cset( self, value ): self.cTemp= float(value) def cget( self ): return self.cTemp celsius= property( cget, cset, doc="Celsius temperature" ) oven= Temperature() oven.farenheit= 450 print oven.celsius # 232.222222222 oven.celsius= 175 print oven.farenheit # 347.0