反射
1.什么是反射
反射是在程序运行的过程中“动态”获取对象的信息,也就是说程序执行到了对象这一步的时候才会去获取对象的信息。
2.为什么要用反射
假设两个程序配和使用,第一个程序的将运行得到的数据传给第二个程序继续运行,第二个程序并不知道数据的信息(值、类型),盲目的执行肯定不行,这个时候就可以用到反射对数据进行查询、获取、等相应的操作。
3.如何实现反射
在python中实现反射很简单,python提供了一些内置函数来帮我们实现反射。
class People:
def __init__(self, name, age):
self.name = name
self.age = age
def say(self):
print(f'{self.name},{self.age}')
obj = People('喜欢唱调rap同学', 18)
# 实现反射机制的步骤
# 1、先通过多dir:查看出某一个对象下可以.出哪些属性来
# print(dir(obj))
# 2、可以通过字符串反射到真正的属性上,得到属性值
# print(obj.__dict__[dir(obj)[-2]]) #喜欢唱调rap同学
接下来就是想办法通过字符串来操作对象的属性了,这就涉及到内置函数hasattr、getattr、setattr、delattr的使用了,四个函数可以通过字符串操作对象的属性
hasattr()
判断对象中有无相应属性,有返回True,没有返回Fals
print(hasattr(obj,'name'))
#True
print(hasattr(obj,'x'))
#False
setattr()
setattr() 设置属性的
setattr(obj,'name','Egon')
#相当于obj,name='Egon'
print(obj.name)
#Egon
#如果不存在属性,则不设置,不会报错,注意没有属性不会为对象添加该属性,和自定义类的属性不同
setattr(obj,'x','Egon')
#用hasattr()做判断,判断之后再设置
if hasattr(obj,'x'):
setattr(obj,'x',111111111) # 10.x=11111
else:
pass
delattr()
delattr() 删除属性
delattr(obj,'name')
print(obj.__dict__)
#{'age': 18}
getattr()
getattr() 获取属性
res1=getattr(obj,'say')
res2=getattr(People,'say')
print(res1)
#<bound method People.say of <__main__.People object at 0x000001800218A8E0>>
print(res2)
#<function People.say at 0x0000018003DBA1F0>
#获取没有的属性就会报错
res3=getattr(obj,'hello')
#AttributeError: 'People' object has no attribute 'hello'
#指定没有属性时的默认返回值,这样就不会报错
res3=getattr(obj,'hello','没有')
print(res3) #没有
#有属性依旧返回属性的值
res4=getattr(obj,'say','没有')
print(res4)
#<bound method People.say of <__main__.People object at 0x000001E60F6CA8E0>>
#用hasattr()做判断再用getattr()获取属性避免出错
if hasattr(obj,'x'):
print(getattr(obj,'x'))
else:
pass
使用案例:
class Ftp:
def put(self):
print('正在执行上传功能')
def get(self):
print('正在执行下载功能')
def interactive(self):
method=input(">>>: ").strip() # method='put'
if hasattr(self,method):
getattr(self,method)()
else:
print('输入的指令不存在')
obj=Ftp()
obj.interactive()
'''
>>put
正在执行上传功能'''