前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Python中反射

Python中反射

作者头像
用户7886150
修改于 2020-12-21 03:05:21
修改于 2020-12-21 03:05:21
8780
举报
文章被收录于专栏:bit哲学院bit哲学院

参考链接: Python中的反射

反射 

运行时,区别于翻译时,指的是程序被加载到内存中执行的时候。 反射,reflection,指的是运行时获取类型定义信息。 一个对象能够在运行时,像照镜子一样,反射出其类型信息。简单说,在Python中,能够通过一个对象,找出其type、class、attribute或method的能力,称为反射或自省。 具有反射能力的函数有type(),isinstance(),callable().dir().getattr()等 

反射相关的函数和用法 

class Point:

    def __init__(self,x,y):

        self.x=x

        self.y=y

    def __str__(self):

        return "{} and {}".format(self.x,self.y)

    def show(self):

        print(self.x,self.y)

p=Point(4,5)

print(p)

print(p.__dict__)

p.__dict__['y']=16

print(p.__dict__)

p.z=10

print(p.__dict__)

print(dir(p))

print(sorted(p.__dir__()))

 上例通过属性字典__dict__来访问对象的属性,本质上就是利用反射的能力,但是上面的例子中,访问的方式不优雅,Python提供了内置的函数 

内建函数意义getattr(object,name[,default])通过name返回object的属性值,当属性不存在,将属性不存在,将使用default返回,如果没有default,则抛出AttributeError,name必须是字符串setattr(object,name,value)object的属性,则覆盖,不存在则新增hasaattr(object,name)判断对象是否有这个名字的属性,name必须为字符串

class Point:

    def __init__(self,x,y):

        self.x=x

        self.y=y

    def __str__(self):

        return "{}{}".format(self.x,self.y)

    def show(self):

        print(self)

p1=Point(4,5)

p2=Point(10,10)

print(repr(p1),repr(p2))

print(p1.__dict__)

setattr(p1,'y',16)

setattr(p1,'z',10)

print(getattr(p1,'__dict__'))

#动态调用方法

if hasattr(p1,'show'):

    print(getattr(p1,'show'))

# 动态增加方法

if not hasattr(Point,'add'):

    setattr(Point,'add',lambda self,other: Point(self.x+other.x,self.y+other.y))

print(Point.add)

print(p1.add)

print(p1.add(p2))

#为实例增加方法,

#为实例增加方法,

if not hasattr(p1,'sub'):

    setattr(p1,'sub',lambda self,other: Point(self.x-other.x,self.y-other.y))

print(p1.sub(p1,p2))

print(p1.__dict__)

print(Point.__dict__)

反射相关的魔术方法 

getattr()、setattr()、delattr()这三个魔术方法。 

getattr() 

class Base:

    n = 0

class Point(Base):

    z = 6

    def __init__(self, x, y):

        self.x = x

        self.y = y

    def show(self):

        print(self.x, self.y)

    def __getattr__(self, item):

        return item

p1=Point(4,5)

print(p1.x)

print(p1.z)

print(p1.n)

print(p1.t)

 实例属性会按照继承关系寻找,如果找不到,就会执行__getattr__()方法,如果没有这个方法,就会抛出AttributeError异常标识找不到属性 查找属性顺序为: instance__dict__---->instance.class.dict---->继承的祖先类(直到object)的__dict__—>找不到—>调用setattr() 

class Base:

    n = 0

class Point(Base):

    z = 6

    def __init__(self, x, y):

        self.x = x

        self.y = y

    def show(self):

        print(self.x, self.y)

    def __getattr__(self, item):

        return item

    def __setattr__(self, key, value):

        print(key,value)

p1=Point(4,5)

print(p1.x)

print(p1.z)

print(p1.n)

print(p1.t)

p1.x=50

print(p1.x)

print(p1.__dict__)

p1.__dict__['x']=60

print(p1.__dict__)

print(p1.x)

 实例通过.点号设置属性,例如self.x=x,就会代用__setattr__(),属性要加到实例的__dict__中,就需要自己完成。 setattr()方法,可以拦截堆实例属性的增加,修改操作,如果要设置生效,需要自己操作实例的__dict__ 

class Base:

    n = 200

class A(Base):

    z = 100

    d={}

    def __init__(self, x, y):

        self.x = x

        setattr(self,'y',y)

        self.__dict__['a']=5

    def __getattr__(self, item):

        print(item)

        return self.d[item]

    def __setattr__(self, key, value):

        print(key,value)

        self.d[key]=value

a=A(4,5)

print(a.__dict__)

print(A.__dict__)

print(a.x,a.y)

print(a.a)

 delattr() 

class Point:

    z=5

    def __init__(self,x,y):

        self.x=x

        self.y=y

    def __delattr__(self,item):

        print(item) p=Point(14,5)

del p.x

p.z=15

del p.z

del p.Z

print(Point.__dict__)

  可以阻止通过实例来删除属性的操作 getattribute 

class  Base:

    n=0

class Point(Base):

    z=6

    def __init__(self,x,y):

        self.x=x

        self.y=y

    def __getattr__(self,item):

        return item

    def __getattribute__(self,item):

        return item

p1=Point(4,5)

print(p1.__dict__)

print(p1.x)

print(p1.z)

print(p1.n)

print(p1.t)

print(Point.__dict__)

print(Point.z)

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

它的return值将作为属性查找的结果如果抛出AttributeError异常,则会直接调用__getattr__方法,因为属性没有找到 __getattribute__方法中为了避免在该方法中无线递归,它的实现应该永远调用基类的同名方法以访问需要的任何属性,需要注意的是,除非明确知道__getattrtbute__方法用来做什么,否则不要使用 

魔术方法意义getattr()当通过搜索实例,实例的类及祖先类查找不到属性,就会调用此方法setattr()通过.访问实例属性,进行增加、修改都要调用它delattr()当通过实例来删除属性时调用此方法getattribute实例所有的属性都从这个方法开始

属性查找顺序: 实例调用__getattribute__()—>instance.dict–>instance.class.dict–>继承的祖先类(直到object)的__dict__–>调用__getattr__()

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
进阶的运维开发(三)- 反射
反射就是通过字符串的形式,导入模块,通过字符串的形式,去模块寻找制定函数并执行。利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动。
奔跑的骆驼
2020/02/27
3460
Python指南:高级程序设计之面向对象程序设计进阶
本节中,我们将更深入地学习 Python 对面向对象的支持,学习很多可以减少必须编写的代码的总量、拓展程序的威力与功能的技术。下面以一个简单的类开始:
王强
2018/08/09
8880
Python 类与继承
self参数用于对当前类中实例的引用,必须作为该类中任何函数的第一个参数,但可以不必命名为 self
回天
2023/04/25
7330
Python 类与继承
Python内置(4)类相关的内置
如果说object是所有对象(objects)的父类,那么type就是所有类(classes)的父亲了。 所有对象继承自object,所有类继承自type type是可用于动态创建新类的内置项。好吧,它实际上有两个用途: 1.如果给定单个参数,它将返回该参数的“类型”,即用于创建该对象的类:
一只大鸽子
2022/12/06
2.4K0
Python语法-类与实例
我们会发现a被删除后,b依旧没有被销毁,这是因为对应每次被引用都会计数器+1,只有计数器为0,才会销毁。
码客说
2021/11/29
5370
python面向对象的多态-类相关内置函数-类内置魔法函数-迭代器协议-上下文管理-04
首先强调,多态不是一种特殊的语法,而是一种状态,特性(多个不同对象可以相应同一个方法,长身不同的结果)
suwanbin
2019/09/26
6860
python面向对象的多态-类相关内置函数-类内置魔法函数-迭代器协议-上下文管理-04
Python中反射和描述器总结
在Python中,能够通过一个对象,找出type、class、attribute或者method的能力,成为反射。
py3study
2020/01/14
9310
Python 开发者不得不知的魔术方法(Magic Method)
来源:j_hao104 my.oschina.net/jhao104/blog/779743 介绍 在Python中,所有以“__”双下划线包起来的方法,都统称为“Magic Method”,例如类的初始化方法 __init__,Python中所有的魔术方法均在官方文档中有相应描述,但是对于官方的描述比较混乱而且组织比较松散。很难找到有一个例子。 构造和初始化 每个Pythoner都知道一个最基本的魔术方法, __init__ 。通过此方法我们可以定义一个对象的初始操作。然而,当调用 x = SomeCl
小小科
2018/05/04
9690
Python 开发者不得不知的魔术方法(Magic Method)
每天一道 python 面试题 - Python反射与自省
自省:自省就是能够获得自身的结构和方法,给开发者可以灵活的调用,给定一个对象,返回该对象的所有属性和函数列表,或给定对象和该对象的函数或者属性的名字,返回对象的函数或者属性实例
公众号---人生代码
2020/05/18
7460
python-__getattr__ 和
python3完全使用了新式类,废弃了旧式类,getattribute作为新式类的一个特性有非常奇妙的作用。查看一些博客和文章后,发现想要彻底理解getattr和getattribute的区别,实际上需要理解python中属性的查找顺序、描述器(descriptor)、__get__、__set__、__dict__等知识。
py3study
2020/01/17
4110
python类之特殊属性和魔术方法
1 实现 StaticMethod 装饰器,实现staticmethod的部分功能
py3study
2020/01/06
1.8K0
Python面向对象的魔术方法
在Python中,所有以__双下划线包起来的方法,都统称为魔术方法。比如最常见的 __init__ 。
职场亮哥
2020/10/10
7580
python 中__setattr__, __getattr__,__getattribute__, __call__使用方法
object._getattr_(self, name) 拦截点号运算。当对未定义的属性名称和实例进行点号运算时,就会用属性名作为字符串调用这个方法。如果继承树可以找到该属性,则不调用此方法 实例instance通过instance.name访问属性name,只有当属性name没有在实例的__dict__或它构造类的__dict__或基类的__dict__中没有找到,才会调用__getattr__。当属性name可以通过正常机制追溯到时,__getattr__是不会被调用的。如果在__getattr__(s
用户1214487
2018/01/24
1.3K0
Datawhale组队学习 -- Task07:类、对象与魔法方法
对象是类的实例。换句话说,类主要定义对象的结构,然后我们以类为模板创建对象。类不但包含方法定义,而且还包含所有实例共享的数据。
余生大大
2022/11/02
3120
Datawhale组队学习 -- Task07:类、对象与魔法方法
Python Magic Method 与 Setup 方法:深入解析与应用
Python 中的魔法方法,也称为双下划线方法或特殊方法,格式为 “方法名”。这些方法无需主动调用,而是在特定场景下由 Python 解释器自动调用。魔法方法的作用是自定义类的行为,以便与内置操作符(例如 +、-、*、/、== 等)和函数(例如 len()、str() 等)交互。
井九
2024/10/12
890
Python中几个常用的类方法
内置方法 说明  __init__(self,...) 初始化对象(实例),在创建新对象时调用  __del__(self) 析构函数,释放对象,在对象被删除之前调用,进行一些清理工作。  __new__(cls,*args,**kwd) 实例的生成操作  __str__(self) 在使用print语句输出实例时被调用  __getitem__(self,key) 获取序列的索引key对应的值,等价于seq[key]  __len__(self) 在调用内联函数len()时被调用  __cmp__(stc,dst) 比较两个对象src和dst  __getattr__(s,name) 获取属性的值  __setattr__(s,name,value) 设置属性的值  __delattr__(s,name) 删除name属性  __getattribute__() __getattribute__()功能与__getattr__()类似  __gt__(self,other) 判断self对象是否大于other对象  __lt__(slef,other) 判断self对象是否小于other对象  __ge__(slef,other) 判断self对象是否大于或者等于other对象  __le__(slef,other) 判断self对象是否小于或者等于other对象  __eq__(slef,other) 判断self对象是否等于other对象
菲宇
2022/12/21
4800
Python魔术方法-Magic Method
目录[-] 介绍 在Python中,所有以“__”双下划线包起来的方法,都统称为“Magic Method”,例如类的初始化方法 __init__ ,Python中所有的魔术方法均在官方文档中有相应描述,但是对于官方的描述比较混乱而且组织比较松散。很难找到有一个例子。 构造和初始化 每个Pythoner都知道一个最基本的魔术方法, __init__ 。通过此方法我们可以定义一个对象的初始操作。然而,当调用 x = SomeClass() 的时候, __init__ 并不是第一个被调用的方法。实际上,还有
jhao104
2018/03/20
8610
Some question about
在 Python 中对于某些 object __dict__ 属性是只读的,比如对于 type object。然而,在 Python2.5-2.6 之前,还是有一些一般性方法可以获取和改变 __dict__ 属性的(without hacking with gc.get_referrents(), that is)。这会导致一些令人费解的错误。
py3study
2020/01/03
6810
面向对象进阶
Wisdom is knowing what to do next , virtue is doing it .
GH
2019/12/16
4450
定制类和黑魔法
定制类 反射     反射又称为自省,指的是程序可以访问、检测和修改它本身状态和行为的一种能力。python中提供了以下四个自检功能的函数。     hasattr(object, name):用来检测object(适用于类、文件、模块或对象,一切皆对象)中有没有一个name字符串对应的方法或属性。
py3study
2020/02/10
4750
相关推荐
进阶的运维开发(三)- 反射
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文