反射指的是一个对象应该具备,可以检测,修改,增加自身属性的能力

反射就是通过字符串操作属性

涉及四个函数,这四个函数就是普通的内置函数,没有双下划线,与print等在使用方法上没有区别

hasattr,getattr,setattr,delattr(他们的具体使用方法和作用见下列代码)

 1 class Person:
 2     def __init__(self,name,age):
 3         self.name = name
 4         self.age = age
 5 
 6 p = Person('sxc',18)
 7 
 8 if hasattr(p,'name'):  # 判断某个对象是否存在某个属性
 9     print(getattr(p,'name'))  # 把这个值当做返回值返回出来
10 
11 print(getattr(p,'gender',None))  # 如果没有这个值后面还可以赋予他一个默认值
12 
13 setattr(p,'id',177)  # 可以为该对象赋予新的属性
14 print(p.id)
15 
16 delattr(p,'id')  # 也可以删除的对象的属性
17 print(p.id)

面向对象之反射、元类

使用场景:

反射其实就是对属性的增删查改,但是如果直接使用内置的__dict__来操作,语法繁琐,不好理解

如果是另一方提供的,无法判断是否是我需要的属性和方法

 

简单的框架设计

框架就是已经实现了最基础的构架,就是所有项目都一样的部分已经完成了。反射被称为框架的基石,框架的设计者不可能提前知道使用者的对象到底是怎么设计的,所以使用者提供给框架的对象必须通过判断验证之后才能正常使用,判断验证就是反射要做的事

需求:实现一个用于处理用户的终端指令的小框架

 1 # 框架部分
 2 def run(plugin):
 3     while True:
 4         cmd = input('请输入您的指令>>>:').strip()
 5         if cmd == 'exit':
 6             break
 7         #  无法判断传入的参数,需要加入反射加以判断
 8         if hasattr(plugin,cmd):  # 取出对应的指令
 9             func = getattr(plugin,cmd)
10             func()  # 执行指令处理
11         else:
12             print('请输入正确的指令')
13     print('退出程序')
14 
15 # 从系统配置文件中截取模块路径和类名
16 module_path, class_name = settings.CLASS_PATH.rsplit('.',1)
17 # 拿到模块
18 mk = importlib.import_module(module_path)
19 # 拿到类
20 cls = getattr(mk,class_name)
21 # 实例化对象
22 obj = cls()
23 # 调用框架
24 run(obj)
项目框架以及运行代码

相关文章: