反射其实就是:通过字符串来映射到对象的属性
这么说你可能不太懂
我们通过代码来说明问题
主代码:
"""
定义一个类,实现一个功能方法
"""
#通过字符串来映射对象属性
class Person:
def __init__(self,name,age):
self.name=name
self.age=age
def talk(self):
print("%s is talking"%self.name)
如果我们想要调用类的方法和属性我们会这样操作:
#调用
obj=Person("shimmer",18)
#访问数据的属性
print(obj.name)#obj.__dict__["name"]
print(obj.age)
#访问方法
print(obj.talk)
得到的结果是:
但是我们还会有下面的这种调用方法:让用户输入方法,或者属性名进行调用:
obj=Person("shimmer",18)
choice=input(">>:")#choice="name"
print(obj.choice)#print(obj.'name')
结果:
看到上面结果显而易见报错了,原因是什么呢,原因就是:# 这是一种错误的访问,对象.属性名后面一定是一个属性名而不是一个字符串
这样就引出了反射这个方法:我们让反射这一方法来办我们实现功能:
1:查找判断是否存在输入的属性或方法名
hasattr方法:hasattr(__obj,__name.str),后面的方法或属性名必须为字符串类型
hasattr(对象名,‘属性或者方法名’)
#判断是否存在属性name
print(hasattr(obj ,'name'))#obj.name,obj.___dict__['name']
#判断代码是否存在方法talk
print(hasattr(obj,'talk'))
2:获取类中的属性和方法
getattr(对象名,‘属性或者方法名’,错误时或者不存在时的返回值)
:
obj1=Person("祝祝",18)
#获取对象的属性
print(getattr(obj1,'name',None))
#获取对象的方法
print(getattr(obj1,'talk',None))
3:向类中添加属性或方法
setattr(对象名,‘属性或方法名’,‘值’)
obj2=Person("winter",18)
#向类中添加属性
print(setattr(obj2,'sex','male'))
print(obj2.sex)
4:删除属性或方法:
delattr(对象名,‘属性或方法名’)
obj2=Person("winter",18)
delattr(obj2,'age')
print(obj2.__dict__)
反射的应用:
"""应用:
定义类:实现功能
通过输入直接获取对象的方法或者属性值,
并对其进行更改删除或者添加"""
class Service:
def run(self):
while True:
enter=input(">>:").strip()#cmd='get a.txt'
cmds=enter.split()#cmds=['get','a.txt']
if hasattr(self,cmds[0]):
func=getattr(self,cmds[0])
func(cmds)
def get(self,cmds):
print('get...',cmds)
def put(self,cmds):
print('put....',cmds)
obj=Service()
obj.run()