Python import 出错的解决方案

在多文件的Python程序编写中,使用 import 引用其他文件中的代码经常会出错。尤其是在涉及到包时,要达到目标往往需要反复调整,通过不断尝试来得到正确的结果。下面针对 Python 中的 import 机制进行一些探索。

绝对导入与相对导入

在Python中,可以将导入分为绝对导入和相对导入。绝对导入通过 import xxx 的形式,从预设的搜索路径中搜索模块进行导入。相对导入则通过 from . import xxx from .a import b from .. import xxx 等形式,在包结构中搜索模块来导入。

早期Python中,默认的导入就隐式地使用了相对导入,而后续Python中的相对导入则需要使用专门的形式了实现。这种相对导入基于包的结构来搜索,因此使用相对导入的模块不能离开包结果。这就使得直接调用的py文件中不能使用这种方式,因为它们本身就作为顶层模块出现,也就不在任何包结构中。

如果在顶层py文件中使用这种方式,会得到类似下面的报错信息。

1
2
3
4
Traceback (most recent call last):
File "/home/ubuntu/workspace/b.py", line 1, in <module>
from . import a
ImportError: attempted relative import with no known parent package

高版本的Python推荐使用绝对导入。但很多时候我们自己编写的包或模块不在默认的搜索路径中。从而得到类似下面的报错信息。

1
2
3
4
Traceback (most recent call last):
File "/home/ubuntu/workspace/b.py", line 1, in <module>
import a
ModuleNotFoundError: No module named 'a'

在这种情况下,我们就需要将所需模块想办法加入到搜索路径中。这一般可以通过对 sys.path 进行修改来实现。

一般,sys.path 由几个部分构成:1. 指定的py文件所在的路径 2. PTYHONPATH 环境变量 3. 内置的 Python 库目录 4. Python 库中给出的 .pth 文件添加的内容。

因此,如果不想在程序中显示地对 sys.path 进行修改,也可以将模块放入默认的搜索路径中,或通过修改 PYTHONPATH 环境变量、修改 .pth 文件内容来成功导入自己的模块。

参考资料