Python描述符:property()函数的小秘密
2024-08-28 09:16:00
描述符:将某种特殊类型的类的实例指派给另一个类的属性(注意:这里是类属性,而不是对象属性)。而这种特殊类型的类就是实现了__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'
最新文章
- 让Git记住用户名和密码
- JS技术大全
- Sublime Text 3安装与使用
- Spring框架学习 - 配置
- Weblogic8.1 的性能优化
- [原]Sublime Text3 搭建16位汇编环境(windows)
- everything 快速搜索有代价
- Effective STL 为包含指针的关联容器指定比较类型
- mysq建表参数设置
- 简单的linux使用命令
- OpenGL 3D旋转的木箱
- tomcat虚拟目录配置
- 第三个Sprint ------第十一天
- Markdown 字体
- MongoDB limit 选取 skip跳过 sort排序 方法
- Socket:读写处理及连接断开的检测
- 2018-2019-1 20189218《Linux内核原理与分析》第二周作业
- 申请startssl免费一年ssl证书(转)
- 配置文件和mybatis文件存放位置导致系统启动不了
- CC3200模块的内存地址划分和bootloader(一)