Python中的相对导入是指在一个包中从其他模块中导入相对路径下的模块。这种方式可使代码更加简洁和易于维护,但如果使用不当,会导致导入失败的问题。
假设有如下包结构:
.├── my_package│ ├── module1.py│ ├── module2.py│ ├── sub_package│ │ ├── __init__.py│ │ └── module3.py│ └── __init__.py└── main.py
现在我们在module1.py中尝试导入module3.py:
# module1.pyfrom .sub_package.module3 import some_functionsome_function()
这是典型的相对导入方式,其中“.”表示当前包。如果我们在main.py中从my_package中导入module1.py:
# main.pyfrom my_package import module1module1.some_function()
在终端中运行main.py程序输出如下错误信息:
Traceback (most recent call last):File "main.py", line 1, infrom my_package import module1File "/path/to/project/my_package/module1.py", line 1, in from .sub_package.module3 import some_functionimportError: attempted relative import with no known parent package
从错误信息可以看出,Python认为module1.py没有任何父级包。这是因为我们在命令行中执行main.py,Python无法获得my_package包的上下文。
解决方法一是修改代码,使用绝对路径导入module3.py:
# module1.pyfrom my_package.sub_package.module3 import some_functionsome_function()
该方式不会受到上下文的影响,但包结构变化时需要手动修改代码。
解决方法二是使用正确的方式执行main.py。建议使用Python的虚拟环境,从项目根目录进入虚拟环境再执行main.py:
$ cd /path/to/project$ source venv/bin/activate$ python main.py
在虚拟环境中运行main.py时,Python会正确解析相对路径导入,从而避免了该问题。