描述符:将某种特殊类型的类的实例指派给另一个类的属性(注意:这里是类属性,而不是对象属性)。而这种特殊类型的类就是实现了__get__,__set__,__delete__这三个方法中的一个或多个的新式类(即继承object)。其中,__get__,__set__,__delete__与__getattr__,__setattr__,__delattr__是很相似的,但是前面3个我们称之为属于描述符的属性方法。

__get__(self, instance, owner)
- 用于访问属性,它返回属性的值
__set__(self, instance, value)
- 将在属性分配操作中(赋值)调用,不返回任何内容
__delete__(self, instance)
- 控制删除操作,不返回任何内容

class MyDescriptor:
def __get__(self, instance, owener):
print('getting...', self, instance, owener)
def __set__(self, instance, value):
print('settiong...', self, instance, value)
def __delete__(self, instance):
print('deleting...', self, instance) class Test:
x = MyDescriptor() >>> test = Test()
>>> test.x
getting... <__main__.MyDescriptor object at 0x0000000002D6A6A0> <__main__.Test object at 0x0000000002D886A0> <class '__main__.Test'>
>>> test
<__main__.Test object at 0x0000000002D886A0>
>>> Test
<class '__main__.Test'>

以上代码中,MyDescriptor类就是描述符类。其中__get__,__set__,__delete__方法中的self是指MyDescriptor类本身的实例对象;instance参数是指属性拥有者的类的实例(本例中是test);__get__第三个参数owner是指属性拥有者的类对象本身(本例中是Test)。其实,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):
return self.fget(instance)
def __set__(self, instance, value):
self.fset(instance, value)
def __delete__(self, instance):
self.fdel(instance) class C:
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 = MyProperty(getX, setX, delX) >>> c = C()
>>> c.x = 'x-man'
>>> c.x
'x-man'
>>> del c.x
>>> c.x
Traceback (most recent call last):
File "<pyshell#79>", line 1, in <module>
c.x
File "<pyshell#72>", line 7, in __get__
return self.fget(instance)
File "<pyshell#74>", line 5, in getX
return self._x
AttributeError: 'C' object has no attribute '_x'

最新文章

  1. 让Git记住用户名和密码
  2. JS技术大全
  3. Sublime Text 3安装与使用
  4. Spring框架学习 - 配置
  5. Weblogic8.1 的性能优化
  6. [原]Sublime Text3 搭建16位汇编环境(windows)
  7. everything 快速搜索有代价
  8. Effective STL 为包含指针的关联容器指定比较类型
  9. mysq建表参数设置
  10. 简单的linux使用命令
  11. OpenGL 3D旋转的木箱
  12. tomcat虚拟目录配置
  13. 第三个Sprint ------第十一天
  14. Markdown 字体
  15. MongoDB limit 选取 skip跳过 sort排序 方法
  16. Socket:读写处理及连接断开的检测
  17. 2018-2019-1 20189218《Linux内核原理与分析》第二周作业
  18. 申请startssl免费一年ssl证书(转)
  19. 配置文件和mybatis文件存放位置导致系统启动不了
  20. CC3200模块的内存地址划分和bootloader(一)

热门文章

  1. ionic错误
  2. Idea 创建maven web项目(手工创建)
  3. 关于javascript原型链的记录
  4. 谈一谈Dijkstra
  5. 洛谷—— P1379 八数码难题
  6. 高速搞定Eclipse的语法高亮
  7. 高仿QQ6.0之側滑删除
  8. OllyDbg 使用笔记 (七)
  9. 通过loosejar清理应用中冗余的jar包
  10. erlang Unicode 处理