背景:
关键字驱动框架,不同的关键字方法分别定义在不同的类,真正执行关键字方法又在不同的类(简称A),这样就需要在执行前,要在文件A下import要使用的模块,如果有很多页面操作或很多模块时,就需要每次都要import,比较麻烦;如果执行时,没有import相应的模块时,会提示xxx not define
动态导入模块结合反射,实现动态调用方法
1、 通过判断当前文件是否包含指定模块,如果不包含,动态导入,声明变量接收动态导入的结果module
2、 反射,结合返回的module,获取指定的类
3、 获取到指定的类后,进行实例化
4、 实例化成功,再次通过反射,获取到指定类的下的方法
5、 获取到方法后,执行,完成

if file_module not in sys.modules:
module = importlib.import_module(file_module) # 动态导入
module_class = getattr(module, class_name) # 反射获取模块下的类
obj = module_class() # 实例化类
else:
obj = globals()[class_name]() # 实例化类
# == 通过反射: 通过已实例化的类,获取到真正要执行的方法 ===
try:
run_fun = getattr(obj, key_fun)
logger.info(f"== 执行步骤:{step_name} ==")
if args:
# 可以传入多个参数
run_fun(*args)
else:
run_fun()
except Exception as e:
logger.exception(f"将字符串: {key_obj},转化为类失败,请检查: {e}")
动态导入,传入的是package.文件,就做了传入当前文件名,获取文件路径
如文件结构
utils
A.py
run
main.py
要在main.py,动态导入A模块,传入的module_name = utils.A,module = importlib.import_module(utils.A)
def search_file_path(self, file_name, root_path, suffix="py", ):
'''
输入文件名,查找文件,并返回当前文件的绝对路径
:param file_name: 文件名,默认不包含后缀
:param suffix: 文件后缀,默认为py
:param root_path: 查找的文件路径
:return:
'''
new_file_name = file_name + "." + suffix
for root, dirs, files in os.walk(root_path):
for name in files:
if name == new_file_name:
res_path = os.path.join(root, name)
return res_path
获取文件路径后,获取其父类文件名
def path_get_parent_name(self, path):
path = Path(path)
return path.parent.name
模块名就由父类文件名 + 文件名,拼接组成,传入到import_module(),进行导入
module = file_parent + "." + file_name
参考:https://blog.csdn.net/weixin_43106092/article/details/118099874
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/281206.html