首页 > 解决方案 > import_module 在 __pycache__ 生成后停止工作

问题描述

我正在动态导入模块

在我的主文件中,在项目根目录中,我做

sys.path.append(os.path.join(os.path.dirname(__file__), "mylib"))

在我的命令导入文件中,mylib/nogui/main.py我做

commands_path = Path(__file__).parent.joinpath("command")
for dirpath, dirnames, filenames in walk(commands_path):
    for file in filenames:
        if file.startswith("cmd_"):
            imported_module = import_module(f"mylib.nogui.command.{file[:file.find('.py')]}")
            imported_module.register()

里面mylib.nogui.command的目录是文件cmd_echo.py

def register():
    print("This works")

如果我第一次运行我的主文件,我会看到:

This works

如果我再次运行它,我会看到:

ModuleNotFoundError:没有名为“mylib.nogui.command.cmd_echo.cpython-37”的模块;'mylib.nogui.command.cmd_echo' 不是一个包

唯一的区别是存在 __pycache__ 文件夹。如果我删除此文件夹,它会再次按预期工作。

标签: python-3.x

解决方案


答案是os.walk默认情况下是递归的

“This works”仍在输出,但它被错误消息隐藏了。我的错。

正在导入目标模块 (cmd_echo) ,但随后os.walk进入 __pycache__ 文件夹并在那里运行动态导入代码,从而产生了此错误。简单的解决方案是在第一个循环之后添加一个中断

commands_path = Path(__file__).parent.joinpath("command")
for dirpath, dirnames, filenames in walk(commands_path):
    for file in filenames:
        if file.startswith("cmd_"):
            imported_module = import_module(f"rantlib.nogui.command.{file[:file.find('.py')]}")
            imported_module.register()
    break

推荐阅读