什么是反射

在Python中,反射指的是通过字符串来操作对象的属性,有四种方法

  • hasattr()判断对象是否含有字符串对应的数据或者功能
  • getattr()根据字符串获取对应的变量名或者函数名
  • setattr()根据字符串给对象设置键值对(名称空间中的名字)
  • delattr()根据字符串删除对象对应的键值对(名称空间中的名字)

基本使用

hasattr使用

  1. class Student(object):
  2. school = '清华大学'
  3. def get(self):
  4. pass
  5. print(hasattr(Student, 'school'))
  6. # True
  7. print(hasattr(Student, 'get'))
  8. # True
  9. print(hasattr(Student, 'post'))
  10. # False

getattr使用

  1. class Student(object):
  2. school = '清华大学'
  3. def get(self):
  4. pass
  5. print(getattr(Student, 'school'))
  6. # 清华大学
  7. print(getattr(Student, 'get'))
  8. # <function Student.get at 0x7feca09c0510>
  9. print(getattr(Student, 'post')) # 不存在报错

setattr使用

  1. class Student(object):
  2. school = '清华大学'
  3. def get(self):
  4. pass
  5. setattr(Student, 'school', '北京大学')
  6. print(Student.school)
  7. # 北京大学

delattr使用

  1. class Student(object):
  2. school = '清华大学'
  3. def get(self):
  4. pass
  5. delattr(Student, 'school')
  6. print(Student.__dict__)

反射实际应用

应用一

  1. class FtpServer:
  2. def serve_forever(self):
  3. while True:
  4. inp = input('input your cmd>>: ').strip()
  5. try:
  6. cmd, file = inp.split()
  7. except ValueError:
  8. print("输入错误")
  9. continue
  10. if hasattr(self, cmd): # 根据用户输入的cmd,判断对象self有无对应的方法属性
  11. func = getattr(self, cmd) # 根据字符串cmd,获取对象self对应的方法属性
  12. func(file)
  13. else:
  14. print("没有此功能")
  15. def get(self, file):
  16. print('Downloading %s...' % file)
  17. def put(self, file):
  18. print('Uploading %s...' % file)
  19. obj = FtpServer()
  20. obj.serve_forever()

应用二

  1. # 利用面向对象编写系统终端功能
  2. class LinuxCmd(object):
  3. def ls(self):
  4. print("正在执行ls")
  5. def cd(self):
  6. print("正在执行cd")
  7. def ll(self):
  8. print("正在执行ll")
  9. obj = LinuxCmd()
  10. def run(obj):
  11. while True:
  12. cmd = input("请输入指令>>>").strip()
  13. if hasattr(obj, cmd):
  14. fun_name = getattr(obj, cmd)
  15. fun_name()
  16. else:
  17. print("command not found: %s" % cmd)
  18. if __name__ == '__main__':
  19. run(obj)

补充

  • 只要在业务中看到关键字对象和字符串(用户输入、自定义、指定) 那么肯定用反射
  • 反射提供了一种不需要考虑代码的前提下 操作数据和功能