文章目录
一、什么是反射机制
反射是一种基于字符串的事件驱动。
它可以通过字符串的形式,导入模块。
通过字符串的形式,去模块寻找指定函数,并执行。
利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员。
二、反射函数
反射函数是对加载到内存中的对象进行操作。
这意味着重新加载模块后,反射操作的对象将复原。
在 Python 中,反射的实现很简单,主要通过以下 4 个函数:
1、getattr()
我们知道变量实际上的是对象的引用。
getattr()
返回对象名,即返回对象的引用。
其中,
第 1 个参数是目标对象
第 2 个参数是 要获取的属性
第 3 个参数default
是当需要获取的属性不存在时,默认返回的值。如果不设置,当属性不存在时,则抛出异常。
2、hasattr()
返回 布尔类型。
该函数通过调用getattr()
实现,即判断是否抛异常。
3、setattr()
4、delattr()
三、用例
1、动态加载模块,并执行指定的一个函数
imp = input("请输入模块:")
dd = __import__(imp)
# 等价于import imp
inp_func = input("请输入要执行的函数:")
f = getattr(dd,inp_func,None)
f() # 执行该函数
这里说下__import__
函数,它用于动态的导入模块,主要用于反射或者延迟加载模块。
import commons
# 等价于
__import__('commons')
import commons as com
# 等价于
com = __import__('commons')
如果需要加载子模块,需要添加参数 fromlist = True
dd = __import__(imp, fromlist = True)
2、基于反射机制模拟web框架路由
url = input("url: ")
target_module, target_func = url.split('/')
m = __import__('lib.'+target_module, fromlist=True)
inp = url.split("/")[-1] # 分割url,并取出url最后一个字符串
if hasattr(m, target_func): # 判断在commons模块中是否存在inp这个字符串
target_func = getattr(m, target_func) # 获取inp的引用
target_func() # 执行
else:
print("404")
参考资料
[1] https://www.cnblogs.com/vipchenwei/p/6991209.html#commentform
[2] https://docs.python.org/3/library/index.html