VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • 模块(2)

import 语句首先核对是否包中有这个子项,如果没有,它假定这是一个模块,并尝试加载它。如果没有找到它,会引发一个 ImportError 异常。

相反,使用类似 import item.subitem.subsubitem 这样的语法时,这些子项必须是包,最后的子项可以是包或模块,但不能是前面子项中定义的类、函数或变量。

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 没有错误!事实上,除非导入的模块需要使用其它包中的同名子模块,否则这是推荐的写法。

6.4.2. 包内引用

如果包中使用了子包结构(就像示例中的 sound 包),可以按绝对位置从相邻的包中引入子模块。例如,如果 sound.filters.vocoder 包需要使用 sound.effects 包中的 echo 模块,它可以 from sound.Effects import echo

你可以用这样的形式 from module import name 来写显式的相对位置导入。那些显式相对导入用点号标明关联导入当前和上级包。以 surround 模块为例,你可以这样用:

from . import echo
from .. import formats
from ..filters import equalizer

需要注意的是显式或隐式相对位置导入都基于当前模块的命名。因为主模块的名字总是 "__main__",Python 应用程序的主模块应该总是用绝对导入。

6.4.3. 多重目录中的包

包支持一个更为特殊的特性, __path__。 在包的 __init__.py 文件代码执行之前,该变量初始化一个目录名列表。该变量可以修改,它作用于包中的子包和模块的搜索功能。

这个功能可以用于扩展包中的模块集,不过它不常用。

Footnotes

[1] 事实上函数定义既是“声明”又是“可执行体”;执行体由函数在模块全局语义表中的命名导入。


相关教程
关于我们--广告服务--免责声明--本站帮助-友情链接--版权声明--联系我们       黑ICP备07002182号