6.4.1. 从 * 导入包那么当用户写下 from sound.effects import * 时会发生什么事?理想中,总是希望在文件系统中找出包中所有的子模块,然后导入它们。这可能会花掉很长时间,并且出现期待之外的边界效应,导出了希望只能显式导入的包。 对于包的作者来说唯一的解决方案就是给提供一个明确的包索引。import 语句按如下条件进行转换:执行 from package import * 时,如果包中的 __init__.py 代码定义了一个名为 __all__ 的列表,就会按照列表中给出的模块名进行导入。新版本的包发布时作者可以任意更新这个列表。如果包作者不想 import * 的时候导入他们的包中所有模块,那么也可能会决定不支持它( import * )。例如, sound/effects/__init__.py 这个文件可能包括如下代码: __all__ = ["echo", "surround", "reverse"]
这意味着 from sound.effects import * 语句会从 sound 包中导入以上三个已命名的子模块。 如果没有定义 __all__ , from sound.effects import * 语句 不会 从 sound.effects 包中导入所有的子模块。无论包中定义多少命名,只能确定的是导入了 sound.effects 包(可能会运行 __init__.py 中的初始化代码)以及包中定义的所有命名会随之导入。这样就从 __init__.py 中导入了每一个命名(以及明确导入的子模块)。同样也包括了前述的 import 语句从包中明确导入的子模块,考虑以下代码: import sound.effects.echo
import sound.effects.surround
from sound.effects import *
在这个例子中,echo 和 surround 模块导入了当前的命名空间,这是因为执行 from...import 语句时它们已经定义在 sound.effects 包中了(定义了 __all__ 时也会同样工作)。 尽管某些模块设计为使用 import * 时它只导出符合某种规范/模式的命名,仍然不建议在生产代码中使用这种写法。 记住,from Package import specific_submodule 没有错误!事实上,除非导入的模块需要使用其它包中的同名子模块,否则这是推荐的写法。
|