问题:谁能解释python的相对导入?
我无法终生让python的相对导入工作。我创建了一个不起作用的简单示例:
目录结构为:
/__init__.py
/start.py
/parent.py
/sub/__init__.py
/sub/relative.py
/start.py
仅包含: import sub.relative
/sub/relative.py
仅包含 from .. import parent
所有其他文件均为空白。
在命令行上执行以下命令时:
$ cd /
$ python start.py
我得到:
Traceback (most recent call last):
File "start.py", line 1, in <module>
import sub.relative
File "/home/cvondrick/sandbox/sub/relative.py", line 1, in <module>
from .. import parent
ValueError: Attempted relative import beyond toplevel package
我正在使用Python 2.6。为什么会这样呢?如何使此沙盒示例正常工作?
回答 0
您正在从“ sub”包中导入。start.py
即使有__init__.py
礼物,它本身也不在包装中。
您需要从以下目录中的一个目录启动程序parent.py
:
./start.py
./pkg/__init__.py
./pkg/parent.py
./pkg/sub/__init__.py
./pkg/sub/relative.py
与start.py
:
import pkg.sub.relative
现在pkg是顶层软件包,您的相对导入应该可以了。
如果您想坚持使用当前的布局,则可以使用import parent
。因为您是start.py
用来启动解释器的,所以该目录start.py
位于python路径中。parent.py
作为一个单独的模块住在那儿。
__init__.py
如果您不将任何内容导入到目录树中更远的脚本中,也可以安全地删除顶层。
回答 1
如果要relative.py
直接调用,即如果您确实要从顶级模块导入,则必须将其显式添加到sys.path
列表中。
它应如何工作:
# Add this line to the beginning of relative.py file
import sys
sys.path.append('..')
# Now you can do imports from one directory top cause it is in the sys.path
import parent
# And even like this:
from parent import Parent
如果您认为上述情况可能导致某种程度的不一致,则可以改用以下方法:
sys.path.append(sys.path[0] + "/..")
sys.path[0]
指的是进入点运行的路径。
回答 2
在python3中签出:
python -V
Python 3.6.5
范例1:
.
├── parent.py
├── start.py
└── sub
└── relative.py
- start.py
import sub.relative
- parent.py
print('Hello from parent.py')
- sub/relative.py
from .. import parent
如果我们这样运行(只是确保PYTHONPATH为空):
PYTHONPATH='' python3 start.py
输出:
Traceback (most recent call last):
File "start.py", line 1, in <module>
import sub.relative
File "/python-import-examples/so-example-v1/sub/relative.py", line 1, in <module>
from .. import parent
ValueError: attempted relative import beyond top-level package
如果我们改变导入 sub/relative.py
- sub/relative.py
import parent
如果我们这样运行:
PYTHONPATH='' python3 start.py
输出:
Hello from parent.py
范例2:
.
├── parent.py
└── sub
├── relative.py
└── start.py
- parent.py
print('Hello from parent.py')
- sub/relative.py
print('Hello from relative.py')
- sub/start.py
import relative
from .. import parent
像这样运行:
PYTHONPATH='' python3 sub/start.py
输出:
Hello from relative.py
Traceback (most recent call last):
File "sub/start.py", line 2, in <module>
from .. import parent
ValueError: attempted relative import beyond top-level package
如果我们更改import in sub/start.py
:
- sub/start.py
import relative
import parent
像这样运行:
PYTHONPATH='' python3 sub/start.py
输出:
Hello from relative.py
Traceback (most recent call last):
File "sub/start.py", line 3, in <module>
import parent
ModuleNotFoundError: No module named 'parent'
像这样运行:
PYTHONPATH='.' python3 sub/start.py
输出:
Hello from relative.py
Hello from parent.py
另外最好使用从根文件夹导入,即:
- sub/start.py
import sub.relative
import parent
像这样运行:
PYTHONPATH='.' python3 sub/start.py
输出:
Hello from relative.py
Hello from parent.py