Python中反射和描述器总结
作者:121502_hl 发布时间:2022-06-18 09:38:22
反射
在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()函数实现为一个数据描述器。
来源:http://blog.51cto.com/1502606/2179050
猜你喜欢
- 1.1.1 摘要 如果说要对数据库进行优化,我们主要可以通过以下五种方法,对数据库系统进行优化。 1. 计算机硬件调优 2. 应用程序调优
- 有这样一个要求,它要创建一个SQL Server查询,其中包括基于事件时刻的累计值。典型的例子就是一个银行账户,因为你每一次都是在不同的时间
- 背景近期看到一篇文章,真的感叹作者的洞察力,在开发时有可能就会犯这样的错误,所以一定要多学习,多实践。其问题就是你在提交事务时,如果中间有其
- antd form表单使用setFildesValue 赋值失效加上this.$nextTick(()=>{})即可this.$nex
- 借助map实现golang中没有set数据结构,一般是通过map实现,因为map的key值是不能重复的示例type empty struct
- 前言深度神经网络是一种目前被广泛使用的工具,可以用于图像识别、分类,物体检测,机器翻译等等。深度学习(DeepLearning)是一种学习神
- jQuery 1.4 源码 449 行(core.js 431 行),判断是否为函数的方法如下(思路来源于 Douglas Crockfor
- 使用触发器触发器发生什么事情之后或之前,会自动执行某条语句,这就是触发器创建触发器创建触发器要给出的4条关键信息:1.唯一的触发器名2.触发
- 本文实例分析了JS重载实现方法。分享给大家供大家参考,具体如下:重载是面向对象语言里很重要的一个特性,JS中没有真正的重载,是模拟出来的(因
- 这篇文章主要介绍了Python中使用gflags实例及原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,
- 一、定义新的自动求导函数在底层,每个原始的自动求导运算实际上是两个在Tensor上运行的函数。其中,forward函数计算从输入Tensor
- 这篇文章主要介绍了JavaScript监听触摸事件代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要
- windows.open()方法详解:window.open(URL,name,features,replace)用于载入指定的URL到新的
- 记录日志是我们程序中必不可少的一个功能,但是日志文件如果没有合理的管理,时间长了几百兆的日志文件就很难分析了(都不想打开看),但是又不可能经
- type是go语法里的重要而且常用的关键字,type绝不只是对应于C/C++中的typedef。搞清楚type的使用,就容易理解go语言中的
- 实验1.1 列表a = [1, 2, 3, 4]for i in a: print(i)  
- python检查值是否已经存在于字典列表中a = [ {'main_color': 're
- 先写一个批处理文件,给个例子。 代码如下:set rq=%date:~0,10% exp system/system的
- df.sort_index()实现按索引排序,默认以从小到大的升序方式排列,如希望按降序排列,传入ascending = Falseimpo
- 什么是deferdefer用来声明一个延迟函数,把这个函数放入到一个栈上, 当外部的包含方法return之前,返回参数到调用方法之前调用,也