包是一种通过用“带点号的模块名”来构造 Python 模块命名空间的方法。 例如,模块名 A.B 表示 A 包中名为 B 的子模块。正如模块的使用使得不同模块的作者不必担心彼此的全局变量名称一样,使用加点的模块名可以使得 NumPy 或 Pillow 等多模块软件包的作者不必担心彼此的模块名称一样。

假设你想为声音文件和声音数据的统一处理,设计一个模块集合(一个“包”)。由于存在很多不同的声音文件格式(通常由它们的扩展名来识别,例如:.wav, .aiff, .au),因此为了不同文件格式间的转换,你可能需要创建和维护一个不断增长的模块集合。 你可能还想对声音数据还做很多不同的处理(例如,混声,添加回声,使用均衡器功能,创造人工立体声效果), 因此为了实现这些处理,你将另外写一个无穷尽的模块流。这是你的包的可能结构(以分层文件系统的形式表示):

      __init__.py               Initialize the sound package
formats/ Subpackage for file format conversions
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ Subpackage for sound effects
__init__.py
echo.py
surround.py
reverse.py
...
filters/ Subpackage for filters
__init__.py
equalizer.py
vocoder.py
karaoke.py
...

当导入这个包时,Python搜索 sys.path 里的目录,查找包的子目录。

The init__.py files are required to make Python treat directories containing the file as packages. This prevents directories with a common name, such as string, unintentionally hiding valid modules that occur later on the module search path. In the simplest case, __init__.py can just be an empty file, but it can also execute initialization code for the package or set the __all variable, described later.

包的用户可以从包中导入单个模块,例如:

这会加载子模块 sound.effects.echo 。但引用它时必须使用它的全名。

导入子模块的另一种方法是

这也会加载子模块 echo ,并使其在没有包前缀的情况下可用,因此可以按如下方式使用:

另一种形式是直接导入所需的函数或变量:

同样,这也会加载子模块 echo,但这会使其函数 echofilter() 直接可用:

请注意,当使用 from package import item 时,item可以是包的子模块(或子包),也可以是包中定义的其他名称,如函数,类或变量。 import 语句首先测试是否在包中定义了item;如果没有,它假定它是一个模块并尝试加载它。如果找不到它,则引发 ImportError 异常。

相反,当使用 import item.subitem.subsubitem 这样的语法时,除了最后一项之外的每一项都必须是一个包;最后一项可以是模块或python包,但不能是前一项中定义的类或函数或变量。

从包中导入

当用户写 from sound.effects import * 会发生什么?理想情况下,人们希望这会以某种方式传递给文件系统,找到包中存在哪些子模块,并将它们全部导入。这可能需要很长时间,导入子模块可能会产生不必要的副作用,这种副作用只有在显式导入子模块时才会发生。

唯一的解决方案是让包作者提供一个包的显式索引。import 语句使用下面的规范:如果一个包的 init__.py 代码定义了一个名为 __all 的列表,它会被视为在遇到 from package import 时应该导入的模块名列表。在发布该包的新版本时,包作者可以决定是否让此列表保持更新。包作者如果认为从他们的包中导入 的操作没有必要被使用,也可以决定不支持此列表。例如,文件 sound/effects/__init__.py 可以包含以下代码:

这意味着 from sound.effects import * 将导入 sound 包的三个命名子模块。

如果没有定义 __all__,from sound.effects import * 语句 不 会从包 sound.effects 中导入所有子模块到当前命名空间;它只确保导入了包 sound.effects (可能运行任何在 __init__.py 中的初始化代码),然后导入包中定义的任何名称。这包括 __init__.py` 定义的任何名称(以及显式加载的子模块)。它还包括由之前的 import 语句显式加载的包的任何子模块。思考下面的代码:

import sound.effects.surround
from sound.effects import *

在这个例子中, echo 和 surround 模块是在执行 from...import 语句时导入到当前命名空间中的,因为它们定义在 sound.effects 包中。(这在定义了 all 时也有效。)

虽然某些模块被设计为在使用 import * 时只导出遵循某些模式的名称,但在生产代码中它仍然被认为是不好的做法。

请记住,使用 from Package import specific_submodule 没有任何问题!实际上,除非导入模块需要使用来自不同包的同名子模块,否则这是推荐的表示法。

子包参考

当包被构造成子包时(与示例中的 sound 包一样),你可以使用绝对导入来引用兄弟包的子模块。例如,如果模块 sound.filters.vocoder 需要在 sound.effects 包中使用 echo 模块,它可以使用 from sound.effects import echo 。

你还可以使用import语句的 from module import name 形式编写相对导入。这些导入使用前导点来指示相对导入中涉及的当前包和父包。例如,从 surround 模块,你可以使用:

from .. import formats
from ..filters import equalizer

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

多个目录中的包
包支持另一个特殊属性, path 。它被初始化为一个列表,其中包含在执行该文件中的代码之前保存包的文件 __init__.py 的目录的名称。这个变量可以修改;这样做会影响将来对包中包含的模块和子包的搜索。

虽然通常不需要此功能,但它可用于扩展程序包中的模块集。

脚注

[1] 实际上,函数定义也是“被执行”的“语句”;模块级函数定义的执行在模块的全局符号表中输入该函数名。

python基础教程:包的创建及导入的更多相关文章

  1. Python 基础教程之包和类的用法

    Python 基础教程之包和类的用法 建立一个文件夹filePackage 在filePackage 文件夹内创建 __init__.py 有了 __init__.py ,filePackage才算是 ...

  2. python基础教程(一)

    之所以选择py交易有以下几点:1.python是胶水语言(跨平台),2.python无所不能(除了底层),3.python编写方便(notepad++等文本编辑器就能搞事情),4.渗透方面很多脚本都是 ...

  3. Python基础教程(第2版 修订版) pdf

    Python基础教程(第2版 修订版) 目录 D11章快速改造:基础知识11.1安装Python11.1.1Windows11.1.2Linux和UNIX31.1.3苹果机(Macintosh)41. ...

  4. Python基础教程(第3版)PDF高清完整版免费下载|百度云盘

    百度云盘:Python基础教程(第3版)PDF高清完整版免费下载 提取码:gkiy 内容简介 本书包括Python程序设计的方方面面:首先从Python的安装开始,随后介绍了Python的基础知识和基 ...

  5. Python基础教程 (第2+3 版)打包pdf|内附网盘链接提取码

                <Python基础教程 第3版>包括Python程序设计的方方面面:首先,从Python的安装开始,随后介绍了Python的基础知识和基本概念,包括列表.元组.字符 ...

  6. 《python基础教程(第二版)》学习笔记 语句/循环/条件(第5章)

    <python基础教程(第二版)>学习笔记 语句/循环/条件(第5章) print 'AB', 123 ==> AB 123 # 插入了一个空格print 'AB', 'CD' == ...

  7. (Python基础教程之十二)Python读写CSV文件

    Python基础教程 在SublimeEditor中配置Python环境 Python代码中添加注释 Python中的变量的使用 Python中的数据类型 Python中的关键字 Python字符串操 ...

  8. python基础教程笔记—即时标记(详解)

    最近一直在学习python,语法部分差不多看完了,想写一写python基础教程后面的第一个项目.因为我在网上看到的别人的博客讲解都并不是特别详细,仅仅是贴一下代码,书上内容照搬一下,对于当时刚学习py ...

  9. Python基础教程学习笔记:第一章 基础知识

    Python基础教程 第二版 学习笔记 1.python的每一个语句的后面可以添加分号也可以不添加分号:在一行有多条语句的时候,必须使用分号加以区分 2.查看Python版本号,在Dos窗口中输入“p ...

随机推荐

  1. 安装ubuntu server时可能会需要的配置

    1.修改源 笔者比较习惯用163的源,配置如下: sudo vi /etc/apt/sources.list 163源为: deb http://mirrors.163.com/ubuntu/ pre ...

  2. Cent OS home下中文目录改成英文目录

    如果安装了中文版的Cent OS之后,root目录和home目录下会出现中文的路径名,如“桌面”.“文档”.“图片”.“公共的”.“下载”.“音乐”.“视频”等目录,这样在命令行上操作十分的不方便,需 ...

  3. Loj #2256. 「SNOI2017」英雄联盟

    题目 我就是个丝薄 如果要用\(dp_i\)表示凑出\(i\)的最小花费显然不可能的 之后大力猜想能凑出来的状态不会很多,我的暴力也告诉我不是很多,好像也确实不多的样子,大概\(4e4\)左右 但是我 ...

  4. [luogu1600] 天天爱跑步

    题面 ​ 直接写正解吧, 不想再写部分分了, 对于\(u\)和\(v\), 我们可以将它拆成两条路径, \(u\)到\(lca(u, v)\)和\(lca(u, v)\)到v, 在这里只分析从\(u\ ...

  5. 文件上传之MultipartFile使用

    转载 文件断点上传,html5实现前端,java实现服务器 一.单/多文件上传使用例子: 工程路径如下 -src |--main.java    --controller    --service  ...

  6. HDU 1715 (大数相加,斐波拉契数列)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1715 大菲波数 Time Limit: 1000/1000 MS (Java/Others)     ...

  7. mysql索引和外键

    innodb外键: 1.CASCADE:从父表删除或更新会自动删除或更新子表中匹配的行 2.SET NULL:从父表删除或更新行,会设置子表中的外键列为NULL,但必须保证子表列没有指定NOT NUL ...

  8. Ubuntu:未找到合法的活动链接

    编辑/etc/NetworkManager/NetworkManager.conf,将managed=false改成managed=true 然后重启. 在桌面环境下,用gedit会出现无法保存的问题 ...

  9. BSGS算法总结

    BSGS算法总结 \(BSGS\)算法(Baby Step Giant Step),即大步小步算法,用于解决这样一个问题: 求\(y^x\equiv z\ (mod\ p)\)的最小正整数解. 前提条 ...

  10. jQuery学习- 获取与设置属性的函数

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...