简单记录一下 Python 模块相关的内容,包括了内置模块、标准模块以及需要单独安装的三方包。而且还有一些经常使用的三方模块,例如 functools、collections、json 等。
模块
Python 中包括了三类的模块:A) 内置的 (builtin),编译在解析器的内部,可以直接使用;B) 标准模块,通常在安装 python 时已经安装,如 gc;C) 第三方包,需要手动安装,如 MySQLdb 。
常用库可参考 The Python Standard Library,其中部分模块可以在源码的 Modules 目录下查看,如 ctypes、gcmodule 等;有些包含在 Python 目录下,如 sysmodule.c、bltinmodule.c 等。
其中,后者的模块会直接编译到 python 可执行文件中,可以通过 nm python 查看,不过对于发行版本,通常已经将调试信息清理过,所以 nm 命令无效。
对于 builtin 模块,可以参考源码中的 builtin_methods[] 数组,包括了 abs、compile、format、filter 等一些常见的函数。
如上,对于 buildin 模块,在源码中,其有效的函数名通常是 buildin_xxx();另外,对于内置模块,不会存在 __file__ 属性,而三方的模块可以通过该属性查看模块的安装路径;当然,也可以通过类似 help(abs) 的命令查看。
对于一些三方模块,可以通过通用的工具进行安装。
对于 CentOS 来说,三方模块通常安装在 /usr/lib64/python2.7/ 目录下。
__builtins__ VS. __builtin__
这个是内置模块中比较容易混淆的两个概念。
在 Python 加载后,可以通过 globals().keys() 查看全局变量,会有一个 __builtins__,包括了直接执行的 Python 以及相应的模块,但是在这两种场景下该值是不同的。
如果是 main 执行,则变量对应 __builtin__ 模块;在加载模块中该值对应 __builtin__.__dict__。也就是 __builtins__ 可能对应 __builtin__,也可能对应 __builtin__.__dict__,这个是 CPython 实现的细节,最好在一个通用模块中不要使用 __builtins__ 。
当然,通常很少会使用该变量,如果需要使用,则需多加注意,在此不再赘述,详细内容可以参考 What’s the deal with __builtins__ vs __builtin__ ,或者可以查看 本地版本 。
三方模块
三方模块也是经常使用的,是对标准库的扩展。
只有当目录包含一个 __init__.py 文件时,才会被认作是一个包,最简单的是一个空文件;当然,也可以在这个文件中执行一些初始化代码,或者为 __all__ 变量赋值。
其中 __all__ 列表用于指定 from package import * 方式导入的名字,示例如下。
三方模块的目录结构为。
各个文件的内容如下。
接下来列举的就是一些常用的三方模块了,可以在使用的时候以供参考。
functools 是 python2.5 引人的,可以参考官方文档 functools — Higher-order functions and operations on callable objects
reduce
这个与 Python 内置的 reduce 相同,每次迭代,将上一次的迭代结果与下一个元素一同执行一个二元的 func 函数。
partial
对于一个带 n 个参数函数,partial 会将第一个参数设置为固定参数,并返回一个带 n-1 个参数函数对象。
collections 模块
该三方模块提供了对内置类型的扩展,是 Python 内建的一个集合模块,提供了许多有用的集合类,包括了多个对象,详细可以查看官方文档 collections High-performance container datatypes 。
defaultdict
在使用 Python 内置的 dict 时,如果引用的 Key 不存在,就会抛出 KeyError,如果希望 key 不存在时,返回一个默认值,就可以用 defaultdict。
注意默认值是调用函数返回的,而函数在创建 defaultdict 对象时传入,除了在 Key 不存在时返回默认值外,该对象的其他行为跟 dict 是完全一样的。
OrderedDict
使用 Python 内置的字典对象时,Key 是无序的,这样当对 dict 做迭代时,无法确定 Key 的顺序,如果要保持 Key 的顺序,可以用 OrderedDict 。
OrderedDict 的 Key 会 按照插入的顺序排列 ,不是 Key 本身排序:
另外,通过 OrderedDict 可以实现一个 FIFO (先进先出) 的 dict,当容量超出限制时,先删除最早添加的 Key:
namedtuple
在 Python 中,tuple 可以 表示不变集合 ,例如,一个点的二维坐标就可以表示成 (1, 2)。但是,看到 (1, 2) 后,很难看出这个 tuple 是用来表示一个坐标的,不过定义一个类又小题大做了,这时就可以使用该对象了。
namedtuple 是一个函数,它用来创建一个自定义的 tuple 对象,并且规定了 tuple 元素的个数,并可以用属性而不是索引来引用 tuple 的某个元素。这样一来,我们用 namedtuple 可以很方便地定义一种数据类型,它具备 tuple 的不变性,又可以根据属性来引用,使用十分方便。
对于如上的示例,可以通过如下方式验证创建的 Point 对象是 tuple 的一种子类:
deque
使用 list 存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为 list 是线性存储,数据量大的时候,插入和删除效率很低。deque 是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:
deque 除了实现 list 的 append() 和 pop() 外,还支持 appendleft() 和 popleft(),这样就可以非常高效地往头部添加或删除元素。