python 反射 (自省)

Posted 北妖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 反射 (自省)相关的知识,希望对你有一定的参考价值。

python中反射是指通过字符串的形式操作对象相关属性。在python中,一切皆对象(只要是对象,都可以通过python的反射机制进行处理)
  在做程序开发中,我们常常会遇到这样的需求:需要执行对象里的某个方法,或需要调用对象中的某个变量,但是由于种种原因我们无法确定这个方法或变量是否存在,这是我们需要用一个特殊的方法 或机制要访问和操作这个未知的方法或变量,这中机制就称之为反射。
  四个可以实现自省的函数 hasattr()  getattr()  setattr() delattr()
  class Stu:
       def __init__(self,name,age,stuid):
           self.name=name
           self.age=age
           self.stuid=stuid


      def study(self):
         print("good good study,day day up")

#判断对象中是否包含该属性 hasattr(Obj,attr)
s=Stu("史莱克",18,6100116003)
print(hasattr(s,"name"))
print(hasattr(s,"play_game"))
 
运行代码,执行结果为:
True
False
 
 
#获取属性
print(getattr(s, "name"))
print(getattr(s,"greet"))#getattr(Obj,attr)当只有两个参数时,访问不存在的属性时,会报错
 
 
运行代码,执行结果为:
史莱克
Traceback (most recent call last):
  File "F:/python/stuDemo/002.py", line 18, in <module>
    print(getattr(s,"greet"))#getattr(Obj,attr)当只有两个参数时,访问不存在的属性时,会报错,将会促发AttributeError
AttributeError: ‘Stu‘ object has no attribute ‘greet‘


print(getattr(s,"grade",90))#getattr(Obj,attr,default),存在三个参数时,如果属性不存在,就会返回一个默认值,不会报错
 
 
运行结果为:
90
 
 
也许你会猜想这样一种情况,getattr()存在三个参数时,如果属性不存在,会在该对象的属性字典中添加该属性,并返回属性值,那么我们就来看一下s的属性字典,结果是;
{‘name‘: ‘史莱克‘, ‘age‘: 18, ‘stuid‘: 6100116003}
很显然,这证明了,我们的猜想是错误的,说明第三个参数只是我们自己设置的默认返回值
 
 
#设置属性setattr(Obj,"key",value)
 
setattr(s,"name","菠萝吹雪")#修改已经存在的属性
print(s.__dict__)
 
 
运行代码,执行结果为:
{‘name‘: ‘菠萝吹雪‘, ‘age‘: 18, ‘stuid‘: 6100116003}
 
 
 
setattr(s,"weight",160)#设置一个不存在的属性,则会在对象的属性字典上添加该属性
print(s.__dict__)
运行代码,执行结果为:
{‘name‘: ‘史莱克‘, ‘age‘: 18, ‘stuid‘: 6100116003, ‘weight‘: 160}
 
 
 
 
#设置方法属性
def play_game():
   print("来啊快活啊")
setattr(s,"play_game",play_game)
print(s.__dict__)
运行结果为:
{‘name‘: ‘史莱克‘, ‘age‘: 18, ‘stuid‘: 6100116003, ‘weight‘: 160, ‘play_game‘: <function play_game at 0x00000000021D2E18>}
 
 
 
#删除属性
delattr(obj,attr)
 
delattr(s,"play_game")
print(s.__dict__)
运行结果为:
{‘name‘: ‘史莱克‘, ‘age‘: 18, ‘stuid‘: 6100116003, ‘weight‘: 160}
 
 
 
delattr(s,"aaaaa")#删除不存在的属性
 
 
结果为:
Traceback (most recent call last):
  File "F:/python/stuDemo/002.py", line 39, in <module>
    delattr(s,"aaaaa")##删除不存在的属性
AttributeError: aaaaa

 
 
 
 





                __setattr__ __delattr__() __getattr__()


class Foo:
x=1
def __init__(self,y):
self.y=y

def __getattr__(self, item):
print(‘----> from getattr:你找的属性不存在‘)


def __setattr__(self, key, value):
print(‘----> from setattr‘)
# self.key=value #这就无限递归了,你好好想想
# self.__dict__[key]=value #应该使用它

def __delattr__(self, item):
print(‘----> from delattr‘)
# del self.item #无限递归了
self.__dict__.pop(item)

#__setattr__添加/修改属性会触发它的执行
f1=Foo(10)
print(f1.__dict__) # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值
f1.z=3
print(f1.__dict__)

#__delattr__删除属性的时候会触发
f1.__dict__[‘a‘]=3#我们可以直接修改属性字典,来完成添加/修改属性的操作
del f1.a
print(f1.__dict__)

#__getattr__只有在使用点调用属性且属性不存在的时候才会触发
f1.xxxxxx
 
 
 

 












































































以上是关于python 反射 (自省)的主要内容,如果未能解决你的问题,请参考以下文章

python中的反射和自省

python学习之自省/反射

Python的自省机制与Python 的反射机制

Python的自省机制与Python 的反射机制

python 反射 (自省)

Python 自省指南与反射