python - 导入再次导入另一个模块的模块时出现 ModuleNotFoundError
问题描述
我的目录结构:
test/
algo/
base.py
func.py
main.py
func.py
进口base
,main.py
进口func
。脚本是:
# base.py
def base():
pass
# func.py
from base import base
def func():
base()
if __name__ == '__main__':
func()
# main.py
from algo.func import func
if __name__ == '__main__':
func()
当我执行时func.py
,很好:
cd test/algo
python func.py # OK
但是main.py
如果失败则运行时:
cd test
python main.py # => ModuleNotFoundError: No module named "base"
现在,如果我为in添加.
前缀:base
func.py
from .base import base # add dot prefix here
def func():
base()
if __name__ == '__main__':
func()
这次运行main.py
正常,但是运行func.py
报错:
ModuleNotFoundError: No module named '__main__.base'; '__main__' is not a package
为什么这个 ?
什么是正确的导入方式base
,func
以便func
可以直接执行,并由 导入main
?
谢谢!
我的环境:MacOS,python3.7.4
解决方案
看起来您将algo/
其视为 Python 包,在这种情况下您可以使用:
# func.py
from algo.base import base
为什么它有效?这是因为 Python 解释器在其模块搜索路径 ( sys.path
) 中添加了执行的文件目录。所以Python看到algo/
它下面有一个目录,import algo
交友工作。
现在,如果您想func.py
直接运行,则会遇到问题:algo/
无法再发现该目录,sys.path
并且您遇到了导入错误,而您的代码是正确的。
完成这项工作的正确方法是告诉 Python 如何找到你的包。
快速而简单的方法是使用 PYTHONPATH 将包含您的包的目录添加到sys.path
:
PYTHONPATH=. python3 algo/func.py
干净的方法将在稍后出现:如果您正确打包项目(例如通过添加 apyproject.toml
和 a setup.cfg
,请参阅https://packaging.python.org/tutorials/packaging-projects/),那么您将能够安装你的包:
pip install .
“安装”的意思是“将包放在 Python 期望的地方”,所以很明显,一旦安装,一切import algo
都会正常工作,无需修改 PYTHONPATH,并且不依赖于您当前的工作目录。
__init__.py
最后一句话,你应该在你的文件夹中放置一个空文件algo/
,使它成为一个合适的 Python 包,没有它,它是Python namespace package
一个有点不同的东西,不是你真正想要的。
而且,你听说过__main__.py
吗?它是您运行时执行的命名空间python3 -m YOUR_PACKAGE
(python3 -m algo
在您的示例中)。
推荐阅读
- python - 本地主机上的 Scrapy splash 连接被拒绝:8050
- python - 如何在条形图中为每个组添加唯一的水平条形标记
- angular - ng build/serve not working 模板中的错误
- mongodb - 如何理解 Bson 时间戳?
- c - 高级 C 问题:请解释 C 构造 *({ foo(&bar); &bar; })
- c - 如何在 C 中将文本文件作为命令行参数
- javascript - 在 javascript 对象中搜索任何值
- kubernetes - 如何为 kubernetes 入口基本身份验证设置辅助密钥
- python - Python,如何快速获取步幅(例如 500)的帧?
- r - R中的子集公式对象