我有一个类似如下的项目层次结构,当我运行 python src/bot/main
时,没有出现错误。但是,如果我运行 python -m src.bot.main
,就会出现错误。为什么?
这是我的文件层次结构:
MyProject
└── src
├── __init__.py
├── bot
│ ├── __init__.py
│ ├── main.py
│ └── sib1.py
└── mod
├── __init__.py
└── module1.py
这是
main.py
的内容:import sys
if __name__ == "__main__":
# sys.path will print the parent folder.
print(sys.path, end="\n\n")
# my problem is on this line.
import sib1
sib1.test()
错误:
Traceback (most recent call last):
File "/usr/local/Caskroom/miniconda/base/envs/test/lib/python3.9/runpy.py", line 197, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/usr/local/Caskroom/miniconda/base/envs/test/lib/python3.9/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/Users/me/Desktop/test_py/src/bot/main.py", line 16, in <module>
import sib1
ModuleNotFoundError: No module named 'sib1'
目前我得出了一些结论:
因为在两种情况下
sys.path
的输出都包括/Users/me/Desktop/MyProject
,所以原因不应该与作用域相关吧?
python -m src.bot.main
和python src/bot/main
的sys.path
输出:
(test) ✔ me Desktop/test_py % python -m src.bot.main
['/Users/me/Desktop/test_py', '/usr/local/Caskroom/miniconda/base/envs/test/lib/python39.zip', '/usr/local/Caskroom/miniconda/base/envs/test/lib/python3.9', '/usr/local/Caskroom/miniconda/base/envs/test/lib/python3.9/lib-dynload', '/usr/local/Caskroom/miniconda/base/envs/test/lib/python3.9/site-packages']
python -m src.bot.main
命令告诉 Python,src
是一个顶级包。在目录结构中,src
下面的所有内容都将被视为src
的子模块/子包。在该组织下,sib1
的正确名称是src.bot.sib1
。就 Python 而言,不存在名为sib1
的顶级模块。 - Brian61354270python -m
是必需的。如果您只需要运行子模块进行测试,可以考虑使用更强大的测试工具,例如doctest(轻量级)或unittest(重量级)。 - Brian61354270src
更具信息性的包名。将你的包文件放置在MyProject/src/MyProject
或者仅仅是MyProject/MyProject
下是很典型的做法。只要确保包含MyProject
(即包)的目录在你的 Python 路径上即可。然后你就可以使用import MyProject.bot.sib1
等语句了。 - Brian61354270main.py
重命名为__main__.py
,以使包直接可执行。例如,python -m MyProject.bot
将执行MyProject.bot.__main__
。 - Brian61354270python -m
运行的包需要在sys.path
中的一个目录中。否则,Python将无法找到它。您当前的工作目录(例如您的示例中的〜/ Desktop / test_py
)始终位于您的Python路径上,因此如果您在包含MyProject
的目录中,则使用python -m MyProject.x.y.z
将起作用。如果您在任何其他目录中,则需要手动将包目录添加到Python路径中。许多IDE允许您在运行配置设置中执行此操作。或者,您可以设置环境变量PYTHONPATH
。 - Brian61354270