python之属性描述符与属性查找规则
描述符
import numbers
class IntgerField:
def __get__(self, isinstance, owner):
print('获取age')
return self.num
def __set__(self, instance, value):
print('设置age值时')
if not isinstance(value, numbers.Integral):
raise ValueError('int need')
self.num = value
def __delete__(self, instance):
pass
class User:
age = IntgerField() // 数据属性描述符,查找优先级最高
user = User()
user.age = 33
print(user.age)
上述的User可以看做数据库中的表,假设我们要控制user中age的赋值类型,固然可以使用以下形式进行拦截:
class User:
age = 33
def __setattr__(self, name, value):
pass // 这里进行类型检测
又或者:
class User:
@property
def age(self):
return self._num
@age.setter
def age(self,value):
self._num = value // 这里进行类型检测
但是这种一两次还行,多了就是在写重复代码,所以就可用上述类IntgerField中定义__get__,__set__等实现属性描述符的方式进行拦截。
getattribute、getattr、setattr、__delattr__等方法用来实现属性查找、设置、删除的一般逻辑,而对属性的控制行为就由属性对象来控制。这里单独抽离出来一个属性对象,在属性对象中定义这个属性的查找、设置、删除行为。这个属性对象就是描述符。
描述符对象一般是作为其他类对象的属性而存在。在其内部定义了三个方法用来实现属性对象的查找、设置、删除行为。这三个方法分别是:
get(self, instance, owner):定义当试图取出描述符的值时的行为。
set(self, instance, value):定义当描述符的值改变时的行为。
delete(self, instance):定义当描述符的值被删除时的行为。
其中:instance为把描述符对象作为属性的对象实例;
owner为instance的类对象。
描述符有数据描述符和非数据描述符之分
只要至少实现__get__、set、__delete__方法中的一个就可以认为是描述符;
只实现__get__方法的对象是非数据描述符,意味着在初始化之后它们只能被读取;
同时实现__get__和__set__的对象是数据描述符,意味着这种属性是可读写的。
属性查找规则
当查找对象上的某个属性时,假设是user.age,顺序先是判断该实例所指向的类以及基类的__dict__中查找,并且如果该属性数据属性描述符,就会调用描述符中的__get__方法
如果该age直接出现在obj.__dict__上,直接返回obj.dict['age']
如果该属性出现在User中或基类中,且该属性是非数据属性描述符,就会调用其__get__方法,如果不是非数据属性描述符,就会调用User或基类的User或基类.dict['age']
如果这些都没有,且User上也没有__getattr__方法,就会报错
最新文章
- 手工给Meteor增加smart package的方法
- JavaScript事件对象与事件处理程序
- Jetty 服务器的知识
- Flash Air 打包安卓 ane
- 【英语】Bingo口语笔记(19) - 如何用英语叙旧
- 抽象类[abstract]_C#
- Class.forName()的作用与使用总结(转载)
- SQL Server 手把手教你使用profile进行性能监控
- 图片验证码demo示例
- 浅析跨域的方法之一 JSONP
- mapreduce shuffle 和sort 详解
- python 上台阶
- OpenCV入门之获取验证码的单个字符(二)
- 用ABP只要加人即可马上加快项目进展(二) - 分工篇
- msql 复杂练习
- 最最最最最基础的SQL Server
- InnoDB Next-Key Lock
- jquery mobile两个页面以及源码(登录与注册) 转
- 《react精髓》读书笔记
- SSH三大框架需要的jar包
热门文章
- C++ 函数的重载和参数默认值
- 谈谈jQuery中的数据类型检测
- 人人开源分模块,非原生html报错,很难查找问题所在,有vue语法
- Applet、Scriptlet与Servlet
- 【编程拾遗】C++的static成员函数与单例模式
- 【转载】双调排序Bitonic Sort,适合并行计算的排序算法
- 阿里云上 配置 vsftpd 配置文件 (一个成功例子)
- CF1091F New Year and the Mallard Expedition
- 【ARTS】01_14_左耳听风-20190211~20190217
- 【转】python编写规范——中标软件有限公司测试中心