反射

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
正在执行上传功能'''

 

posted @ 2025-01-10 14:10  向闲而过  阅读(120)  评论(0)    收藏  举报