我不理解pep-0404中的以下内容:
在 Python 3 中,包内的隐式相对导入已不可用,只支持绝对导入和显式相对导入。此外,星号导入(例如 from x import *)仅允许在模块级别代码中使用。
什么是相对导入?Python2 中还有哪些地方可以使用星号导入?请给出示例进行解释。
我不理解pep-0404中的以下内容:
在 Python 3 中,包内的隐式相对导入已不可用,只支持绝对导入和显式相对导入。此外,星号导入(例如 from x import *)仅允许在模块级别代码中使用。
什么是相对导入?Python2 中还有哪些地方可以使用星号导入?请给出示例进行解释。
相对导入是指您在导入当前脚本/包相关的软件包时发生的情况。
例如,考虑以下树形结构:
mypkg
├── base.py
└── derived.py
现在,您的derived.py
需要从base.py
获取内容。在Python 2中,您可以通过以下方式完成(在derived.py
中):
from base import BaseThing
Python 3不再支持隐式导入,因为无法明确你需要相对还是绝对的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))
有关相对导入,请参见文档。 相对导入是指从一个模块相对于该模块所在位置进行导入,而不是绝对从sys.path
导入。
至于import *
,Python 2允许在函数内部使用星号导入,例如:
>>> def f():
... from math import *
... print sqrt
在Python 2中(至少是最近版本),这一点会发出警告。在Python 3中,不再允许这样做,您只能在模块的顶层执行星号导入(不能在函数或类内部执行)。
from .sister import foo
from . import brother
from ..aunt import bar
from .. import uncle
import .brother
在 Python 2 和 3 中都是无效的语法。 - Rodrigo E. Principeimport ..uncle
。已修复。哦,我在想什么呢...可能被说“尼!”的骑士分心了... - Akseli Palén添加了 Michał Górny 回答中的另一种情况:
请注意,相对导入是基于当前模块的名称。由于主模块的名称始终为 "__main__
",因此用作 Python 应用程序主模块的模块必须始终使用绝对导入。
__package__
。而且模块级别的__package__
属性是可写的,所以即使__name__ == "__main__"
,您可以通过设置__package__
属性来指定相对导入解析的位置。 - wim
python derived.py
时,这当然会失败。 - Milo Bem