Python无需显式硬编码导入模块的实现及动态导入报错解决
问题原因
exec执行import语句时,导入的模块仅存在于exec内部的局部作用域,不会被加入当前代码的全局命名空间,因此直接访问basicCommands会触发未定义错误- 使用
exec做动态导入存在安全隐患,Python官方推荐使用标准库importlib实现动态导入需求
修复方案
第一步:修改loadCommandFiles函数
你需要把导入的模块存入全局可访问的结构里,方便后续调用,修改后的代码如下:
import importlib import tkinter as tk import os # 全局存储所有导入的命令模块 command_modules = {} def main(): global main_entry main_entry = tk.Entry(font = ("Helvetica", 30, "bold")) main_entry.pack() main_entry.focus_set() main_entry.bind('<Return>', entry_parser) def entry_parser(dontCare): entry_string = main_entry.get() # 后续可以直接从command_modules里取模块属性做逻辑处理 def loadCommandFiles(): current_path = os.getcwd() for file in os.listdir(current_path): if file.endswith(".py") and not file.endswith("jarvis.py"): module_name = file.replace(".py", "") # 动态导入模块 imported_module = importlib.import_module(module_name) # 存入全局字典,键是模块名,值是模块对象 command_modules[module_name] = imported_module # 测试访问basicCommands的commands变量 print(command_modules[module_name].commands) terminal = tk.Tk() terminal.overrideredirect(True) terminal.geometry("+{}+{}".format(int(terminal.winfo_screenwidth()/2 - terminal.winfo_reqwidth()/2), int(terminal.winfo_screenheight()/2 - terminal.winfo_reqheight()/2))) loadCommandFiles() main() terminal.mainloop()
第二步:后续使用方式
后续你需要访问任意动态导入模块的属性时,直接从command_modules字典里取即可,比如要获取basicCommands的commands列表:
commands_list = command_modules["basicCommands"].commands
扩展优化建议
- 可以统一规范所有命令模块的导出结构,比如每个模块都必须导出
commands列表和对应的执行函数,后续新增模块只要符合规范就能自动识别,不需要修改原有代码 - 如果命令模块放在单独的子目录下,还可以在子目录下加
__init__.py文件,调整import路径即可实现子目录模块的批量导入
内容的提问来源于stack exchange,提问作者thekingoflorda
相关产品推荐
相关产品推荐

