4-路径导入
0x-wen

python文件运行时路径导入的问题

错误提示:ModuleNotFoundError: No module named ‘xxxx’

解决这个问题首先要明白Python运行时,Python解释器会按照一定的搜索路径来查找模块和包。

可以通过sys.path查看具体信息

1
2
import sys
print(sys.path)
1
['/Users/jw/Documents/github/abcd/b', '/opt/homebrew/Cellar/python@3.12/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python312.zip', '/opt/homebrew/Cellar/python@3.12/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12', '/opt/homebrew/Cellar/python@3.12/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/lib-dynload', '/opt/homebrew/lib/python3.12/site-packages', '/Users/jw/Documents/github/abcd']
  1. 当前工作目录:即列表下标为0的元素,解释器会首先在当前目录中搜索模块,当前工作目录是指在运行Python脚本时所在的目录
  2. PYTHONPATH环境变量:PYTHONPATH环境变量可以用来指定额外的模块搜索路径。它是一个包含多个目录路径的列表,Python解释器会按照列表中的顺序进行搜索。
1
2
# 可以通过以下命令在终端查看
echo $PYTHONPATH

这种方式比较隐蔽,不常用,需要操作者知情才会去查看此环境变量

  1. 系统默认路径:Python解释器会在一组默认的系统路径中搜索模块。这些路径包括Python标准库的位置以及安装的第三方库的位置。【参考上述path路径中展示,除最后一个元素和第一个元素外】

解决方案

1
2
3
4
5
6
7
abcd/
├── a/
│ ├── init.py
│ └── m.py # m.py中有一个变量 aa = 11
└── b/
├── init.py
└── mb.py # 在此路径下运行 mb.py 文件 并打印出变量 aa
1
2
3
4
5
6
7
# mb.py
from a.m import aa
print(aa)

File "/Users/jw/Documents/github/abcd/b/mb.py", line 29, in <module>
from a.m import aa
ModuleNotFoundError: No module named 'a'

将模块a添加至path路径中

1
2
3
4
5
6
7
8
9
10
import sys
from pathlib import Path

root_path = Path(__file__).resolve().parent.parent
sys.path.append(str(root_path)) # 将root_path添加到PATH,并会在此模块下搜索
print(sys.path) # 此处会输出path的所有内容


from a.m import aa
print(aa) # 成功输出变量信息

类似场景

1
2
3
4
5
6
7
8
abcd/
├── a/
│ ├── init.py
│ └── m.py # m.py中有一个变量 aa = 11
└── b/
├── init.py
└── mb.py # 在此路径下运行 mb.py 文件 并打印出变量 aa
└ main.py # 程序主入口
1
2
3
# mian.py
from a.m import aa
print(aa)

main.py 无需添加至PATH即可成功输出aa变量的原因现在知道了吗?

根据上述结论推导:

  1. main.py文件在运行时,会在当前工作目录下搜索包,即能找到a模块也可以找到b模块,无需添加
由 Hexo 驱动 & 主题 Keep
总字数 42.8k