import 语句 python3 中的变化
- 2024-12-13 08:36:00
- admin 原创
- 142
问题描述:
我不明白pep-0404中的以下内容
在 Python 3 中,包内的隐式相对导入不再可用 - 仅支持绝对导入和显式相对导入。此外,星型导入(例如 from x import *)仅允许在模块级代码中使用。
什么是相对导入?python2 中还有哪些地方允许使用星号导入?请举例说明。
解决方案 1:
每当您导入相对于当前脚本/包的包时,就会发生相对导入。
例如,考虑下面的树:
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))
解决方案 2:
有关相对导入,请参阅文档。相对导入是指从相对于该模块位置的模块导入,而不是绝对导入sys.path
。
至于import *
,Python 2 允许在函数内进行星号导入,例如:
>>> def f():
... from math import *
... print sqrt
Python 2(至少是最新版本)会对此发出警告。Python 3 不再允许这样做,并且您只能在模块的顶层(而不是在函数或类内)进行星型导入。
解决方案 3:
要同时支持 Python 2 和 Python 3,请使用如下所示的显式相对导入。它们是相对于当前模块的。它们从 2.5 开始受支持。
from .sister import foo
from . import brother
from ..aunt import bar
from .. import uncle
解决方案 4:
在 Michał Górny 的回答中添加了另一个案例:
请注意,相对导入基于当前模块的名称。由于主模块的名称始终为“ __main__
”,因此打算用作 Python 应用程序主模块的模块必须始终使用绝对导入。