Python中反射和描述器总结


Posted in Python onSeptember 23, 2018

反射

在Python中,能够通过一个对象,找出type、class、attribute或者method的能力,成为反射。

函数与方法

内建函数:

getattr(object,name[,degault])  通过name返回object的属性值,当属性不存在,将使用default返回,如果没有default,则抛出AttributeError。Name必须为字符串。

setattr(object,name,value)  object的属性存在,则覆盖,不存在,新增。

hasattr(object,name)  判断对象是否有这个名字的属性,name必须为字符串

反射相关的魔术方法

__getattr__()

一个类的属性会按照继承关系找,如果找不到,就会执行__getattr__()方法,如果没有这个方法,就会抛出AttributeError异常表示找不到属性。

查找顺序为:

Instance.__dict__-->instance.__class__.__dict__-->继承的祖先类(直到object)的__dict__---找不到--> 调用__getattr__()

__setattr__()

可以拦截对实例属性的增加、修改操作,如果要设置生效,需要自己操作实例的__dict__

__delattr__()

可以阻止通过实例删除属性的操作,但是通过类依然可以删除属性。

__getattribute__()

实例的所有的属性访问,第一个都会调用__getattribute__方法,它阻止了属性的查找,该方法应该返回值或者抛出一个AttributeError异常

它的return值将作为属性查找的结果

如果抛出AttributeError异常,则会直接调用__gutattr__方法,因为表述属性没有找到。

__grtattribute__方法中为了避免在该方法中无限的递归,他的实现应该永远调用基类的同名方法以访问需要的任何属性,例如:object.__getattribute__(self,name)。一般不使用该方法

魔术方法

__getattr__()

当通过搜索实例、实例的类及祖先类查不到属性,就会调用此方法

__setattr__()

通过.访问实例的属性,进行增加,修改都要调用它

__delattr__()

当通过实例来删除属性时调用此方法

__getattribute__()

实例所有的属性调用都从这个方法开始

属性查找顺序:

实例调用__getattribute__() --> Instance.__dict__-->instance.__class__.__dict__-->继承的祖先类(直到object)的__dict__---找不到--> 调用__getattr__() 。

描述器:

描述器定义

在python中,一个类实现了__get__、__set__、__delete__三个方法中的任何一个方法,就是描述器。

如果仅实现了__get__,就是非数据描述符non-data descriptor

同时实现了__get__,__set__就是数据描述符 data descriptor

如果一个类的类属性设置为描述器实例,那么它被称为owner属主

属性查找顺序

实例的__dict__优先于非数据描述器,数据描述器优先于实例的__dict__

有__delete__方法有同样的效果,有了这个方法,也是数据描述器。

描述器在python中应用非常广泛,python的方法(包括staticmethod()和class method())都实现为非数据描述器,因此,实现可以重新定义和覆盖方法。这允许单个实例获取与同一个类的其他实例不同的行为。

Python中property()函数实现为一个数据描述器。

Python 相关文章推荐
简单的Apache+FastCGI+Django配置指南
Jul 22 Python
简单总结Python中序列与字典的相同和不同之处
Jan 19 Python
Python实现中一次读取多个值的方法
Apr 22 Python
使用matplotlib画散点图的方法
May 25 Python
Python清空文件并替换内容的实例
Oct 22 Python
Python基于百度云文字识别API
Dec 13 Python
python把转列表为集合的方法
Jun 28 Python
用Python识别人脸,人种等各种信息
Jul 15 Python
python requests抓取one推送文字和图片代码实例
Nov 04 Python
Python3.7 基于 pycryptodome 的AES加密解密、RSA加密解密、加签验签
Dec 04 Python
TensorFlow2.0矩阵与向量的加减乘实例
Feb 07 Python
Python使用re模块验证危险字符
May 21 Python
python3实现爬取淘宝美食代码分享
Sep 23 #Python
ubuntu16.04制作vim和python3的开发环境
Sep 23 #Python
Python实现注册、登录小程序功能
Sep 21 #Python
用于业余项目的8个优秀Python库
Sep 21 #Python
Python 经典面试题 21 道【不可错过】
Sep 21 #Python
python使用folium库绘制地图点击框
Sep 21 #Python
在python中安装basemap的教程
Sep 20 #Python
You might like
PHP+SQL 注入攻击的技术实现以及预防办法
2010/12/29 PHP
Zend Framework教程之配置文件application.ini解析
2016/03/10 PHP
php递归函数怎么用才有效
2018/02/24 PHP
laravel 事件/监听器实例代码
2019/04/12 PHP
JavaScript中void(0)的具体含义解释
2007/02/27 Javascript
javascript结合html5 canvas实现(可调画笔颜色/粗细/橡皮)的涂鸦板
2013/04/27 Javascript
jQuery删除节点的三个方法即remove()detach()和empty()
2013/12/27 Javascript
Extjs表单常见验证小结
2014/03/07 Javascript
JS中getYear()和getFullYear()区别分析
2014/07/04 Javascript
一个js过滤空格的小函数
2014/10/10 Javascript
transport.js和jquery冲突问题的解决方法
2015/02/10 Javascript
JavaScript中判断函数、变量是否存在
2015/06/10 Javascript
javascript实现textarea中tab键的缩排处理方法
2015/06/26 Javascript
AngularJS基础教程之简单介绍
2015/09/27 Javascript
RequireJS入门一之实现第一个例子
2015/09/30 Javascript
AngularJS equal比较对象实例详解
2016/09/14 Javascript
vue 设置proxyTable参数进行代理跨域
2018/04/09 Javascript
微信小程序按钮去除边框线分享页面功能
2018/08/27 Javascript
vue-cli 3.x配置跨域代理的实现方法
2019/04/12 Javascript
Vue.extend实现挂载到实例上的方法
2019/05/01 Javascript
vue-cli3.0实现一个多页面应用的历奇经历记录总结
2020/03/16 Javascript
Vue仿百度搜索功能
2020/12/28 Vue.js
Python XlsxWriter模块Chart类用法实例分析
2019/03/11 Python
利用python 读写csv文件
2020/09/10 Python
Django websocket原理及功能实现代码
2020/11/14 Python
CSS3自定义滚动条样式的示例代码
2017/08/21 HTML / CSS
使用HTML5在网页中嵌入音频和视频播放的基本方法
2016/02/22 HTML / CSS
初级软件工程师面试题 Junior Software Engineer Interview
2015/02/15 面试题
表彰先进的通报
2014/01/31 职场文书
幼儿园小班家长寄语
2014/04/02 职场文书
舞蹈专业求职信
2014/06/13 职场文书
化工工艺设计求职信
2014/06/25 职场文书
党员个人公开承诺书
2014/08/29 职场文书
2014年人事科工作总结
2014/11/19 职场文书
检讨书模板大全
2015/05/07 职场文书
关于Vue Router的10条高级技巧总结
2021/05/06 Vue.js