4-1-模块-宏伟蓝图
模块是最高级别的程序组织单元,它将程序代码和数据封装起来以便重用。
每一个文件都是一个模块,并且模块导入其他模块之后就可以使用导入模块定义的变量名。
模块可以由两个语句和一个重要的内置函数进行处理:
- **import:**使客户端(导入者)以一个整体获取一个模块。
- **from:**允许客户端从一个模块文件中获取特定的变量名。
- **imp.reload:**在不中止 Python 程序的情况下,提供了一个种重新载入模块文件代码的方法。
1. Import 如何工作
程序第一次导入指定文件时,会执行三个步骤:
-
- 找到模块文件。
-
- 编译成位码(需要时)。
-
- 执行模块的代码来创建其所定义的对象。
这三个步骤只在程序执行时,模块第一次导入时才会进行。在这之后,导入相同模块时,会跳过这三个步骤,而只提取内存中已加载的模块对象。
2. 模块搜索路径
Python 的模块搜索路径是以下主要组件组合而成的结果:
- 程序的主目录。
- PYTHONPATH 的目录(如果已经进行了设置)。
- 标准链接库目录。
- 任何 .pth 文件的内容(如果存在的话)。
- 第三方扩展的 site-packages 主目录。
2.1 配置搜索路径
搜索路径的 PYTHONPATH 和路径文件部分允许我们调整导入查找文件的地方。
在 Windows 上,把 PYTHONPATH 设置为分号隔开的一串目录:
1 | c:\pycode\utilities;d:\pycode\package1 |
或者创建一个名为 pydirs.pth
的文本文件,其内容如下所示:
1 | c:\pycode\utilities |
2.2 sys.path 列表
可以通过打印内置的 sys.path 列表查看模块搜索路径在机器上的实际配置。
2.3 模块文件选择
Python 会选择在搜索路径中第一个符合导入文件名的文件。
模块来源
import b 形式的 import 叙述可能会加载:
- 源代码文件 b.py。
- 字节码文件 b.pyc。
- 目录 b,包导入。
- 编译扩展模块(通常用 C 或 C++ 编写),导入时使用动态连接(例如,Linux 的 b.so 以及 Cygwin 和 Windows 的 b.dll 或 b.pyd)。
- 用 C 编写的编译好的内置模块,并通过静态连接至 Python。
- ZIP 文件组件,导入时会自动解压缩。
- 内存内映像,对于 frozen 可执行文件。
- Java 类,在 Jython 版本的 Python 中。
- .NET 组件,在 IronPython 版本的 Python 中。
import hooks 和 ZIP 文件
重新定义 Python 中 import 操作所做的事也是可能的,也就是使用 import hook。这些 hook 可以让 import 做各种有用的事,例如,从归档中加载文件,执行解密等。
Python 使用这些 hook 让文件可以直接从 ZIP 文件中导入,归档后的文件会在导入时自动解压缩。
最佳化字节码文件
Python 也支持最佳化字节码文件 .pyo,这种文件在创建和执行时要加上 -O 这个 Python 标志位。因为这些文件执行时会比普通的 .pyc 文件快一点,然而,它们并没有频繁地使用。
1 |