Python强大的内置模块collections-

Python015

Python强大的内置模块collections-,第1张

collections 是 Python 的一个内置模块,所谓内置模块的意思是指 Python 内部封装好的模块,无需安装即可直接使用。

Python 提供了很多非常好用的基本类型,比如不可变类型 tuple,我们可以轻松地用它来表示一个二元向量。

namedtuple 是一个函数,它用来创建一个自定义的 tuple 对象,并且规定了 tuple 元素的个数,并可以用属性而不是索引来引用 tuple 的某个元素。

如此一来,我们用 namedtuple 可以很方便地定义一种数据类型,它具备 tuple 的不变性,又可以根据属性来引用,使用十分方便。

本示例中我们使用了一个三维坐标 x,y,z 来定义一个 tuple 对象,对象元素有3个,然后通过坐标值来引用相应的值即可。

deque是栈和队列的一种广义实现,deque是 "double-end queue" 的简称;

deque支持线程安全、有效内存地以近似O(1)的性能在 deque 的两端插入和删除元素,尽管 list 也支持相似的操作,但是它主要在固定长度操作上的优化,从而在 pop(0) 和 insert(0,v)(会改变数据的位置和大小)上有O(n)的时间复杂度。

在数据结构中,我们知道队列和堆栈是两个非常重要的数据类型,一个先进先出,一个后进先出。

在 python 中,使用 list 存储数据时,按索引访问元素很快,但是插入和删除元素就很慢,因为 list 是线性存储,数据量大的时候,插入和删除效率很低。

deque是为了高效实现插入和删除操作的双向链表结构,非常适合实现队列和堆栈这样的数据结构。

defaultdict是内置数据类型 dict 的一个子类,基本功能与 dict 一样,只是重写了一个方法__missing__(key)和增加了一个可写的对象变量 default_factory。

使用 dict 字典类型时,如果引用的 key 不存在,就会抛出 KeyError。如果希望 Key 不存在时,返回一个默认值,就可以用 defaultdict。

OrderedDict类似于正常的词典,只是它记住了元素插入的顺序,当在有序的词典上迭代时,返回的元素就是它们第一次添加的顺序。这样 dict 就是一个有序的字典。

使用 dict 时,key 是无序的。在对 dict 做迭代时,我们无法确定 key 的顺序。但是如果想要保持 key 的顺序,可以用 OrderedDict。

内置的模块(python解释器自带的)、第三方(开发者编写的模块)、自定义的模块。

1、先从内存中找。

2、再从内置模块中找。

3、最后从sys.path中找(环境变量)一定要分清楚谁是执行文件谁是被导入文件sys返回的是一个列表,里面放了一些文件的路径,但是第一个路径永远是文件所在的文件夹。

Python的解释环境是很好用,但是如果我们需要编写一个大型的程序的时候,解释环境就完全不够用了。这个时候我们需要将python程序保存在一个文件里。通常这个文件是以.py结尾的。

对于大型的应用程序来说,一个文件可能是不够的,这个时候我们需要在文件中引用其他的文件,这样文件就叫做模块。

模块是一个包含Python定义和语句的文件。文件名就是模块名后跟文件后缀 .py 。在模块内部,模块名可以通过全局变量 __name__ 获得。

还是之前的斐波拉赫数列的例子,我们在fibo.py文件中存放了函数的实现:

编写完毕之后,我们可以在Python的解释环境中导入它:

然后直接使用即可:

常用的函数,我们可以将其赋值给一个变量:

或者,我们在导入的时候,直接给这个模块起个名字:

或者导入模块中的函数:

每个模块都有它自己的私有符号表,该表用作模块中定义的所有函数的全局符号表。因此,模块的作者可以在模块内使用全局变量,而不必担心与用户的全局变量发生意外冲突。

前面我们提到了可以使用import来导入一个模块,并且 __name__ 中保存的是模块的名字。

和java中的main方法一样,如果我们想要在模块中进行一些测试工作,有没有类似java中main方法的写法呢?

先看一个例子:

在模块中,我们需要进行一个判断 __name__ 是不是被赋值为 "__main__"。

我们这样来执行这个模块:

以脚本执行的情况下,模块的 __name__ 属性会被赋值为 __main__ , 这也是例子中为什么要这样写的原因。

看下执行效果:

如果是以模块导入的话,那么将不会被执行:

使用import导入模块的时候,解释器首先会去找该名字的内置模块,如果没找到的话,解释器会从 sys.path变量给出的目录列表里寻找。

sys.path的初始目录包括:

要想查看模块中定义的内容,可以使用dir函数。

上面的例子列出了当前模块中定义的内容,包括变量,模块,函数等。

我们可以给dir加上参数,来获取特定模块的内容:

java中有package的概念,用来隔离程序代码。同样的在Python中也有包。

我们看一个Python中包的例子:

上面我们定义了4个包,分别是sound,sound.formats, sound.effects, sound.filters。

__init__.py 可以是一个空文件,也可以执行包的初始化代码或设置 __all__ 变量。

当导入的时候, python就会在 sys.path 路径中搜索该包。

包的导入有很多种方式,我们可以导入单个模块:

但是这样导入之后,使用的时候必须加载全名:

如果不想加载全名,可以这样导入:

那么就可以这样使用了:

还可以直接导入模块中的方法:

然后这样使用:

如果一个包里面的子包比较多,我们可能会希望使用 * 来一次性导入:

那么如何去控制到底会导入effects的哪一个子包呢?

我们可以在 __init__.py 中定义一个名叫 __all__ 的列表,在这个列表中列出将要导出的子包名,如下所示:

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

如果没有定义 __all__,from sound.effects import * 语句 不会 从包 sound.effects 中导入所有子模块到当前命名空间;它只会导入包 sound.effects。

Import 可以指定相对路径,我们使用 . 来表示当前包, 使用 .. 来表示父包。

如下所示: