我有一个像这样的python包目录:
proj/
mod_a/
__init__.py
x.py
submod_x/
__init__.py
y.py
mod_b/
__init__.py
z.py
使用x.py:
import submod_x.y
z.py:
import sys, os.path
sys.path.append(os.path.abspath('../'))
import mod_a.x
现在我跑的时候:
$ python2 z.py
我用y.py
编写完成的东西但是当我跑步时:
$ python3 z.py
我有一个例外:
Traceback (most recent call last):
File "z.py", line 4, in <module>
import mod_a.x
File ".../proj/mod_a/x.py", line 1, in <module>
import submod_x.y
ImportError: No module named 'submod_x'
我想知道导入包时Python 2和Python 3之间有什么区别,如何在Python 3中使用绝对导入导入位于其父目录中的包?
答案 0 :(得分:3)
感谢用户的帮助。 仔细阅读PEP后,我现在能够自己回答这个问题。
首先,我需要知道3种进口:
绝对进口。
import sys
此处,“sys”是可从sys.path($ PATH)访问的模块或包名称。 Python默认情况下将脚本所在的目录插入到sys.path中。换句话说,如果我在python3 mod_b/z.py
下运行proj/
,python会将proj/mod_b/
插入到sys.path。
明确的相对进口。
from ..mod_a import x
导入相对于当前模块的模块(可能不当前工作目录$ PWD)。 python3 doc中清楚地描述了基本原理。还有一些来自PEP-0328的例子。
注意:显式相对导入必须始终使用from <> import <>
。
隐式相对进口。
import submod_x.y
在python2中,这样的import语句将隐式导致相对于当前模块的导入。即如果我在python2 mod_a/x.py
下运行proj/
,则当前模块为x
,并且将正确导入相对于submod_x.y
的模块x
。声明from submod_x import y
等同于from .submod_x import y
作为上面提到的显式相对导入。
然而,显而易见的是隐式相对进口可能与绝对进口混淆,如PEP-0328中所述。根据{{3}},python3不再支持隐式相对导入。
其次,在包中运行脚本在PEP-0404中被视为Guido的反模式......
我在这方面以及主要机制的任何其他提议方面都是-1。唯一的用例似乎是运行脚本,这些脚本恰好位于模块的目录中,我一直将其视为反模式。为了让我改变主意,你必须让我相信它不是。
您可能会想到email。如果您打算这样做,请参阅上面链接中的帖子以获取解决方案。
以下是其他一些可能对您有帮助的帖子:
答案 1 :(得分:0)
我认为你应该在x.py中执行此操作:
import mod_a.submod_x.y
从文件位置进行绝对导入是使用绝对模块名称完成的,或者像这样:
from . import submod_x.y