从实际应用角度来看,模块实际上对应于Python程序文件,每一个文件都是一个模块,并且模块导入其他模块模块之后就可以使用该模块中定义的变量名和函数。模块基本上可以由两个语句和一个重要的内置函数进行处理:
- import,可以导入整个模块内容
- from 从模块中选取要导入的对象
- imp.reload 在不终止Python程序的情况下,重新导入模块。
从抽象的视角来看,模块至少有三个角色:
- 代码重用。模块中的代码可以被多次导入其它模块。
- 系统命名空间的划分。模块中的变量或对象都存在于模块中,命名空间也封装于模块中。不同模块之间的可以有效避免冲突。
- 实现共享服务和数据
在Python中,顶层文件(也叫脚本)主要包括了处理的主要流程,它常常导入了一个或多个其他模块的内容。这些模块提供特定的功能,导入模块后,就可以在顶层文件中获得该模块内容的访问权和使用权。
标准库模块是Python自带的一些常用模块,可以在任何安装了python的情况下使用。
import如何工作
- 找到模块文件
- 编译成位码(需要时执行)
- 执行模块的代码来创建其所定义的对象
这三个步骤是在程序第一次执行模块导入时才会进行。当导入相同模块时,会跳过这三个步骤,而只是提取内存中已加载的模块对象。从技术上讲,当执行模块导入时会检查sys.modules的表,如果表中没有要导入的模块则开始执行导入,如果表中不存在,将会按照这三个步骤开始执行模块导入。
搜索
当第一次导入一个模块时,Python程序要按照一定的路径顺序查找模块。Python程序会按照以下4个路径顺序来查找模块
- 程序主目录
该路径是Python程序是自动定义的。当运行一个顶层文件时,主目录就是包含该顶层文件的目录。这个目录是Python程序最先查找的目录,意味着这里的模块可能覆盖后面路径中(包括标准库中)同文件名的模块。 - PYTHONPATH目录(如果已经设置)
Python会从左至右搜索PYTHONPATH环境变量中的路径,这些目录是可以是平台用户自定义的。可以用这种方式来扩展自己的Python路径 - 标准链接库目录
Python程序会自动搜索安装在机器上的Python目录 - 任何.path文件的内容(如果文件存在)
允许用户将路径一行行列在文本文件中,将该文本放在适当的目录下。Python程序也会读取文本文件中的内容,将目录添加到搜索路径中。文本文件可以放在安装目录的顶层,或者在标准库所在位置的目录下。在linux路径下,可能是在/usr/local/lib/python3.5/dist-packages下
从技术上讲,Python将这四个路径组合成为一个包含路径的列表(sys.path),并按按照先后顺序来依次搜索当中的模块。也可以通过打印sys.path来显示当前搜索的所有路径。也可以通过修改sys.path变量来改变搜索路径,当然这个修改只能在Python程序运行时有效,程序退出后失效。
模块文件选择
Python程序会在搜索的路径中,按照下面的顺序找到第一个符合模块名称的文件:
- 源代码文件 .py
- 字节码文件.pyc
- 目录,包导入
- 编译扩展模块,导入时动态链接
- 用c编写的编译好的内置模块,并通过静态链接至Python
- ZIP文件组件,导入时会自动解压
- 内存映像文件,对于frozen可执行文件
- Java类,在Jypthon版本的Python
- .NET组件,在IronPython版本的Python
正常情况下,不要让Python程序去按照上述顺序来判断导入的模块,在编程时,应该让模块文件名称更明显更特殊一些。
高级的模块选择概念
一般来说,导入模块的工作就是按照上面的步骤来执行的。在Python中重新定义import也是有可能的,这可以让Python程序在默认导入一个模块时,执行某一些钩子脚本,比如解密,归档等操作。更多细节可以参考Python标准库手册中关于内置的__import__函数的说明,这个函数是实际执行的import语句的可定制工具
小结
import和from语句是Python模块导入的核心,在导入时,先从预定的搜索路径中搜索模块名。模块是为python程序提供结构,让程序将其逻辑分割成为一些独立完备的软件组件。一个模块与另一个模块完全独立和分离,在不使用import的情况下,是不能相互访问的。