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 相关文章推荐
Python使用MONGODB入门实例
May 11 Python
Python2.x版本中基本的中文编码问题解决
Oct 12 Python
Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例
Dec 12 Python
Python中pymysql 模块的使用详解
Aug 12 Python
pytorch中的embedding词向量的使用方法
Aug 18 Python
python getpass模块用法及实例详解
Oct 07 Python
python解析多层json操作示例
Dec 30 Python
浅析python表达式4+0.5值的数据类型
Feb 26 Python
基于python 将列表作为参数传入函数时的测试与理解
Jun 05 Python
python和node.js生成当前时间戳的示例
Sep 29 Python
Python提取视频中图片的示例(按帧、按秒)
Oct 22 Python
Python turtle编写简单的球类小游戏
Mar 31 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实现将GB编码转换为UTF8
2006/11/25 PHP
php画图实例
2014/11/05 PHP
php中base64_decode与base64_encode加密解密函数实例
2014/11/24 PHP
PHP内核探索之变量
2015/12/22 PHP
浅析PHP开发规范
2018/02/05 PHP
extjs 学习笔记 四 带分页的grid
2009/10/20 Javascript
js动画(animate)简单引擎代码示例
2012/12/04 Javascript
js实现键盘操作实现div的移动或改变的原理及代码
2014/06/23 Javascript
深入理解JavaScript系列(36):设计模式之中介者模式详解
2015/03/04 Javascript
jQuery判断元素上是否绑定了指定事件的方法
2015/03/17 Javascript
深入浅出理解javaScript原型链
2015/05/09 Javascript
javascript委托(Delegate)blur和focus用法实例分析
2015/05/26 Javascript
jquery实现的用户注册表单提示操作效果代码分享
2015/08/28 Javascript
JS判断form内所有表单是否为空的简单实例
2016/09/09 Javascript
Bootstrap模态框案例解析
2017/03/05 Javascript
layui实现动态和静态分页
2018/04/28 Javascript
JS加密插件CryptoJS实现AES加密操作示例
2018/08/16 Javascript
浅谈Vue.use的使用
2018/08/29 Javascript
JS遍历JSON数组及获取JSON数组长度操作示例【测试可用】
2018/12/12 Javascript
vue获取data数据改变前后的值方法
2019/11/07 Javascript
Vue双向绑定实现原理与方法详解
2020/05/07 Javascript
vue 自定指令生成uuid滚动监听达到tab表格吸顶效果的代码
2020/09/16 Javascript
vue实现列表拖拽排序的功能
2020/11/02 Javascript
python实现文件名批量替换和内容替换
2014/03/20 Python
在Python的Flask框架中使用日期和时间的教程
2015/04/21 Python
python模块之re正则表达式详解
2017/02/03 Python
python 中文件输入输出及os模块对文件系统的操作方法
2018/08/27 Python
python实现PCA降维的示例详解
2020/02/24 Python
使用pygame实现垃圾分类小游戏功能(已获校级二等奖)
2020/07/23 Python
Python虚拟环境virtualenv创建及使用过程图解
2020/12/08 Python
整理HTML5移动端开发的常用触摸事件
2016/04/15 HTML / CSS
世界上最伟大的马产品:Equiderma
2020/01/07 全球购物
创先争优标语
2014/06/27 职场文书
小学四年级班务总结该怎么写?
2019/08/16 职场文书
Vue的生命周期一起来看看
2022/02/24 Vue.js
使用python创建股票的时间序列可视化分析
2022/03/03 Python