可以有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