之前的property的用法见:http://blog.csdn.net/sinat_41104353/article/details/79250415
描述符就是将某种特殊类型的类的实例指派给另一个类的属性。
特殊类型的要求:至少实现以下三个方法中的一个
①__get__(self, instance, owner) 用于访问属性,它返回属性的值
②__set__(self, instance, value) 将在属性分配(赋值)操作中调用,不返回任何内容
③__delete__(self, instance) 控制删除操作,不返回任何内容
这三个方法属于描述符属性的方法。
>>> class MyDecriptor:
def __get__(self, instance, owner):
print("getting...", self, instance, owner)
def __set__(self, instance, value):
print("setting...", self, instance, value)
def __delete__(self, instance):
print("deleting...", self, instance)
>>> class Test:
x = MyDecriptor() #MyDecriptor()是x的描述符
>>> test = Test()
>>> test.x
getting... <__main__.MyDecriptor object at 0x0000000003301240> <__main__.Test object at 0x0000000003036320> <class '__main__.Test'> #第一个参数self是描述符类本身的一个实例;第二个参数instance是拥有描述符类对象的一个实例,即test;第三个参数owner是拥有者的类本身,即Test
>>> test.x = "X-man"
setting... <__main__.MyDecriptor object at 0x0000000003301240> <__main__.Test object at 0x0000000003036320> X-man #出现等号赋值方法,就会调用__set__方法
>>> del test.x
deleting... <__main__.MyDecriptor object at 0x0000000003301240> <__main__.Test object at 0x0000000003036320>
不难推测,property就是一个描述符类,下面我们一起来定义一个自己的property类:
>>> class MyProperty:
def __init__(self, fget=None, fset=None, fdel=None):
self.fget = fget
self.fset = fset
self.fdel = fdel
def __get__(self, instance, owner): #当get被调用的时候,我们要去执行获取的方法fget
return self.fget(instance)
def __set__(self, instance, value):
return self.fset(instance, value)
def __delete__(self, instance):
return self.fdel(instance)
>>> class C:
def __init__(self):
self._x = None #_x表示不希望被外部直接访问
def getX(self):
return self._x
def setX(self, value):
self._x = value
def delX(self):
del self._x
x = MyProperty(getX, setX, delX)
>>> c = C()
>>> c.x = 'X-man'
>>> c.x
'X-man'
>>> c._x
'X-man'