一、概念
通常的 Python 程序的构架是指:将一个程序分割为源代码文件的集合以及将这些部分连接在一起的方法。
Python 的程序构架可表示为:
一个 Python 程序就是一个模块的系统。它有一个顶层文件(启动后可运行程序)以及多个模块文件(用来导入工具库)。注:标准库模块:Python 中自带的实用模块,也称为标准链接库,这个集合体大约有 200 多个模块,包含于平台不相关的常见程序设计任务:操作系统接口、对象永久保存、文字匹配模式、网络和 Internet 脚本、GUI 建构等。注意:这些工具都不是 Python 语言的组成部分,但是,可以在任何安装了标准 Python 的情况下,导入适当的模块来使用。
二、模块
概念:模块是 Python 中最高级别的组织单元,它将程序代码和数据封装起来以便重用。其实,每一个以扩展名 .py 结尾的 Python 文件都是一个模块。模块的三个角色:
1)代码重用;
2)系统 命名空间的划分(模块可理解为变量名的封装,即模块就是命名空间);
3)实现共享服务和数据。
程序和模块:Python 中,程序是作为一个主体的、顶层的文件来构造的,配合有零个或多个支持的文件,而后者这些文件都可以称作模块(顶层的文件也可以作为模块使用,但一般情况不作为模块)。顶层文件:包含了程序的主要的控制流程:即需要运行来启动应用的文件。模块文件:可看做是工具的仓库(即装满了工具),这些工具是用来收集顶层文件(或其他可能的地方)使用的组件。顶层文件与模块文件:顶层文件使用了在模块文件中定义的工具,为这些模块也使用了其他模块所定义的工具。模块的执行环境:模块包含变量、函数、类以及其他的模块(如果导入的话),而函数也有自己的本地变量。下图描述了模块内的情况以及与其他模块的交互,即 模块的执行环境:
可见:模块可以被导入,但模块也会导入和使用其他模块,这些模块可以用 Python 或其他语言(如,C 语言)写成。
三、import(导入)
概念:一个文件可通过导入一个模块(文件)读取这个模块的内容,即导入从本质上讲,就是在一个文件中载入另一个文件,并且能够读取那个文件的内容。一个模块内的内容通过这样的属性(object . attribute)能够被外界使用。导入是 Python 中程序结构的重点所在。
1、import a module 四种方式
1) import X:导入模块 X,并在当前命名空间(namesapce)创建该模块的引用。可以使用:X.name 引用定义在模块 X 中的属性。
2) from X import *:导入模块 X,并在当前命名空间,创建该模块中所有公共对象(名字不以__开头)的引用。即你能使用普通名字(直接是 name)去引用模块 X 中的属性,但是 X 本身没有定义,不能使用 X.name。并且如果命名空间中原来有同名的 name 定义时,它将会被新的 name 取代。
3) from X import a, b, c:导入模块 X,并在当前命名空间创建该模块给定对象的引用。
4) X = __import__(‘X’):类似(1)import X,区别在于:该方式显示指定了 X 为当前命名空间中的变量。使用方法一致。
2、当 import a module 时,Python 都做了哪些事情?
import a moudle 时,首先,Python 解释器会检查 module registry(sys.moudles)部分,查看是否该模块先前就已经导入,如果 sys.modules 中已经存在(即已注册),则使用当前存在的模块对象即可。如果 sys.modules 中还不存在,则:
1)创建一个新的、空的 module 对象(本质上是一个字典);
2)在 sys.modules 字典中插入该模块对象;
3)加载该模块代码所对应的对象(如果需要,可以先编译好(编成位码))。
然后在新的模块命名空间、执行该模块代码对象(code object)。所有由该代码指定的变量均可以通过该模块对象引用。注:上述步骤只有在模块第一次执行时才会执行。在这之后,导入相同模块时,会跳过这些步骤,而只提取内存中已加载的模块对象。这是个有意设计的结果。因为导入(找文件 – 将其编译成字节码 – 运行代码)是一个开销很大的操作以至于每个程序运行不能够重复多于一次。若想要 Python 在同一次会话中再次运行文件(不停止和重新启动会话),需要调用内置的 reload(重载)函数(该函数返回值为一个 Python 模块对象)。
3、import 搜索路径顺序
1)程序的主目录:即程序(顶层)文件所在的目录(有时候不同于当前工作目录(指启动程序所在目录))。
2)PYTHONPATH(环境变量)目录
3)标准链接库目录
4)任何 .pth 文件的内容(如果存在的话):安装目录下找到该文件,以行的形式加入所需要的目录即可。
以上四个组件组合起来就变成了 sys.path,其保存了模块搜索路径在机器上的实际配置,可以通过打印内置的 sys.path 列表来查看这些路径。导入时,Python 会由左至右搜索列表中的每个目录,知道找到对应的 module 为止。其中搜索路径的(1)和(3)是系统自动定义的,而(2)(4)可以用于拓展路径,从而加入自己的源代码目录。另外:也可以使用 sys.path 在 Python 程序运行时临时修改模块搜索路径。如:
import sys
sys.path.append(‘C:\\mydir’)
注:以上 sys.path 的设置方法只是在程序运行时临时生效的,一旦程序结束,不会被保留下来。而前面介绍的四种路径配置方式则会在操作系统中永久保存下来。
References:
1、《Python 学习手册》第 3 章、第 18 章以及第 19 章 2、Importing Python Modules from effot.org