Python动态导入多模块并条件调用函数异常排查
问题排查与解决方案
核心错误原因
模块导入逻辑错误:
原代码中__import__("modules", globals(), locals(), [file], 0)的调用方式,实际返回的是modules包本身,而非目标子模块(如modules.one)。同时传入的file是带.py后缀的文件名,不符合Python模块名的规范要求。遍历字典时操作对象错误:
for module in modules循环遍历的是字典的键(文件名字符串),而非实际导入的模块对象。对字符串调用dir()自然无法找到模块内的sayBye属性。
修正后的代码
main.py
import glob import os.path import importlib # 加载modules目录下的py文件,提取合法模块名(去掉.py后缀) module_files = glob.glob("modules/*.py") module_names = [os.path.splitext(os.path.basename(f))[0] for f in module_files] modules = {} for name in module_names: print(f"Importing {name}.py") # 使用importlib导入子模块,直接获取目标模块对象 module = importlib.import_module(f"modules.{name}") modules[name] = module print("--") # 遍历实际导入的模块对象 for module in modules.values(): if hasattr(module, "sayBye"): say_bye = getattr(module, "sayBye") if callable(say_bye): say_bye() else: print("sayBye is not a function.") else: print("sayBye could not be found.")
关键修改说明
- 替换导入方式:用
importlib.import_module替代__import__,直接指定完整子模块路径(如modules.one),返回值就是目标模块对象,避免__import__的返回值歧义。 - 规范模块名:从文件名中去除
.py后缀,得到符合Python要求的模块名。 - 遍历模块对象:改用
modules.values()遍历实际导入的模块对象,而非字典的键字符串。 - 优化属性检测:用
hasattr()替代"sayBye" in dir(),更直接高效地检测模块是否包含目标属性。
验证输出
运行修正后的代码,将得到符合预期的输出:
Importing one.py one.py says hi! Importing two.py two.py says hello! Importing three.py three.py says hello! -- sayBye is not a function. two.py says bye! sayBye could not be found.
内容的提问来源于stack exchange,提问作者Ole Kristian Møller-Hansen
相关产品推荐
相关产品推荐

