193

我不明白pep-0404的以下内容

在 Python 3 中,包内的隐式相对导入不再可用 - 仅支持绝对导入和显式相对导入。此外,星型导入(例如 from x import *)只允许在模块级代码中使用。

什么是相对进口?在 python2 中允许在哪些其他地方进行星形导入?请举例说明。

4

4 回答 4

295

每当您导入相对于当前脚本/包的包时,就会发生相对导入。

例如,考虑以下树:

mypkg
├── base.py
└── derived.py

现在,您derived.py需要来自base.py. 在 Python 2 中,您可以这样做(在 中derived.py):

from base import BaseThing

Python 3 不再支持这一点,因为它不明确你想要 'relative' 还是 'absolute' base。换句话说,如果base系统中安装了一个名为的 Python 包,那么您将得到错误的包。

相反,它要求您使用显式导入,在类似路径的基础上显式指定模块的位置。你derived.py会看起来像:

from .base import BaseThing

前导.说“base从模块目录导入”;换句话说,.base映射到./base.py.

类似地,有..前缀会在目录层次结构中上升,例如../..mod映射到../mod.py),然后...上升两级(../../mod.py),依此类推。

但是请注意,上面列出的相对路径是相对于当前模块 ( derived.py) 所在的目录,而不是当前工作目录。


@BrenBarn已经解释了明星进口案例。为了完整起见,我不得不说同样的话;)。

例如,您需要使用几个math函数,但您只在一个函数中使用它们。在 Python 2 中,你被允许是半懒惰的:

def sin_degrees(x):
    from math import *
    return sin(degrees(x))

请注意,它已经在 Python 2 中触发了警告:

a.py:1: SyntaxWarning: import * only allowed at module level
  def sin_degrees(x):

在现代 Python 2 代码中,您应该这样做,而在 Python 3 中,您必须执行以下任一操作:

def sin_degrees(x):
    from math import sin, degrees
    return sin(degrees(x))

或者:

from math import *

def sin_degrees(x):
    return sin(degrees(x))
于 2012-08-29T08:08:42.613 回答
15

有关相对导入,请参阅文档。相对导入是指从相对于该模块位置的模块导入,而不是绝对 from sys.path

至于import *,Python 2 允许在函数中导入星号,例如:

>>> def f():
...     from math import *
...     print sqrt

在 Python 2(至少是最新版本)中会为此发出警告。在 Python 3 中不再允许这样做,您只能在模块的顶层进行星号导入(不能在函数或类内部)。

于 2012-08-29T07:32:12.087 回答
13

要同时支持 Python 2 和 Python 3,请使用如下的显式相对导入。它们是相对于当前模块的。从 2.5开始支持它们。

from .sister import foo
from . import brother
from ..aunt import bar
from .. import uncle
于 2015-10-20T18:16:37.850 回答
5

在 Michał Górny 的回答中添加了另一个案例:

请注意,相对导入基于当前模块的名称。由于主模块的名称始终为“ __main__”,因此用作 Python 应用程序的主模块的模块必须始终使用绝对导入。

于 2018-08-09T20:27:11.347 回答