在上一篇中我们讲到了函数,如果你想在所编写的别的程序中重用一些函数的话,应该怎么办?正如你可能想象到的那样,答案是模块(Modules)。我们这一篇就从模块说起。
模块
为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在 Python 中,一个.py
文件就称之为一个模块(Module)。包括 Python 内置的模块和来自第三方的模块。点击查看 Python 的所有内置函数。
dir 函数
内置的dir()
函数能够返回由对象所定义的名称列表。
如果这一对象是一个模块,则该列表会包括函数内所定义的函数、类与变量。该函数接受参数。
如果参数是模块名称,函数将返回这一指定模块的名称列表。
如果没有提供参数,函数将返回当前模块的名称列表。
包
变量通常位于函数内部,函数与全局变量通常位于模块内部。如果你希望组织起这些模块的话,就需要包(Packages)。
Python 引入了按目录来组织模块的方法,称为包(Package)。它是一种能够方便地分层组织模块的方式。包是指一个包含模块与一个特殊的 __init__.py 文件的文件夹,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。__init__.py可以是空文件,也可以有Python代码,因为__init__.py本身就是一个模块。
使用模块
在一个模块中,我们可能会定义很多函数和变量,但有的函数和变量我们希望给别人使用,有的函数和变量我们希望仅仅在模块内部使用。在 Python 中,是通过_
前缀来实现的。
类似__xxx__
这样的变量是特殊变量,可以被直接引用,但是有特殊用途,比如__author__
,__name__
就是特殊变量。我们自己的变量一般不要用这种变量名。
类似_xxx
和__xxx
这样的函数或变量就是非公开的(private),不应该被直接引用,比如_abc
,__abc
等。
安装第三方模块
对应的 pip 命令是pip3
。
默认情况下,Python 解释器会搜索当前目录、所有已安装的内置模块和第三方模块,搜索路径存放在sys
模块的path
变量中:
数据结构
数据结构(Data Structures)是一种结构,能够将一些数据聚合在一起。换句话说,它们是用来存储一系列相关数据的集合。 Python 中有四种内置的数据结构——列表(List)
、元组(Tuple)
、字典(Dictionary)
和集合(Set)
。
列表
列表是一种用于保存一系列有序项目的集合,也就是说,你可以利用列表保存一串项目的序列。应用方括号[]
括起来,元素之间用逗号隔开。
一旦你创建了一张列表,你可以添加、移除或搜索列表中的项目。既然我们可以添加或删除项目,我们会说列表是一种可变的(Mutable)数据类型,即这种类型是可以被改变的。
Python 为 list 类
提供了一种append
方法,能够允许你向列表末尾添加一个项目。列表的sort
方法对列表进行排序,这一方法影响到的是列表本身,而不会返回一个修改过的列表。del
语句会从列表中移除相应的项目。最后,想了解列表对象定义的所有方法,可通过help(list)
语句。
元组
元组(Tuple)用于将多个对象保存到一起。你可以将它们近似地看作列表,但是元组不能提供列表类能够提供给你的广泛的功能。
元组的一大特征类似于字符串,它们是不可变的,也就是说,你不能编辑或更改元组。
元组是通过特别指定项目来定义的,在指定项目时,你可以给它们加上括号()
,并在括号内部用逗号进行分隔。
元组通常用于保证某一语句或某一用户定义的函数可以安全地采用一组数值,意即元组内的数值不会改变。
字典
字典就像一本地址簿,如果你知道了他或她的姓名,你就可以在这里找到其地址或是能够联系上对方的更多详细信息,换言之,我们将键值(Keys)
(即姓名)与值(Values)
(即地址等详细信息)联立到一起。在这里要注意到键值必须是唯一的,正如在现实中面对两个完全同名的人你没办法找出有关他们的正确信息。
另外要注意的是你只能使用不可变的对象(如字符串)作为字典的键值,但是你可以使用可变或不可变的对象作为字典中的值。
在字典中,你可以通过使用符号构成d = {key : value1 , key2 : value2}
这样的形式,来成对地指定键值与值。在这里要注意到成对的键值与值之间使用冒号分隔,而每一对键值与值则使用逗号进行区分,它们全都由一对花括号括起。
另外,字典中的成对的键值—值配对不会以任何方式进行排序。如果你希望为它们安排一个特别的次序,只能在使用它们之前自行进行排序。
你将要使用的字典是属于 dict 类
下的实例或对象。
切片:
切片是一个重要的概念。切片为序列的一部分,那么什么是序列呢?
序列的主要功能是资格测试(Membership Test)和索引操作(Indexing Operations),它们能够允许我们直接获取序列中的特定项目。
上面的列表、元组和字符串都可以看作序列(Sequence)的某种表现形式。它们都拥有一种切片(Slicing)运算符。
切片操作:
Python 从 0 开始计数,因此索引操作也从 0 算起,索引操作也可以使用负数,此时位置计数将从队列的末尾开始。如 shoplist[-1] 指的是序列的最后一个项目。
在切片操作中,第一个数字(冒号前面的那位)指的是切片开始的位置,第二个数字(冒号后面的那位)指的是切片结束的位置。
如果第一位数字没有指定,Python 将会从序列的起始处开始操作。如果第二个数字留空,Python 将会在序列的末尾结束操作。
也可以在切片操作中提供第三个参数,这一参数将被视为切片的步长(Step)(在默认情况下,步长大小为 1)。当步长为 2 时,我们得到的是第 0、2、4…… 位项目。当步长为 3 时,我们得到的是第 0、3……位项目。
要注意的是切片操作会在开始处返回 start,并在 end 前面的位置结束工作。也就是说,序列切片将包括起始位置,但不包括结束位置。
举例:
shoplist[1:3] 返回的序列的一组切片将从位置 1 开始,包含位置 2 并在位置 3 时结束,因此,这块切片返回的是两个项目。类似地,shoplist[:] 返回的是整个序列。
shoplist[:-1] 强返回一组序列切片,其中不包括序列的最后一项项目,但其它所有项目都包含其中。
如果你希望创建一份诸如序列等复杂对象的副本(而非整数这种简单的对象(Object)),必须使用切片操作来制作副本。
如果你仅仅是将一个变量名赋予给另一个名称,那么它们都将“查阅”同一个对象,容易造成麻烦。
集合
集合(Set)是简单对象的无序集合(Collection)。
当集合中的项目存在与否比起次序或其出现次数更加重要时,我们就会使用集合。通过使用集合,你可以测试某些对象的资格或情况,检查它们是否是其它集合的子集,找到两个集合的交集,等等。
>>> bri = set(['brazil', 'russia', 'india'])
>>> 'india' in bri
True
>>> 'usa' in bri
False
参考链接:
简明Python教程(电子书可阅读)
廖雪峰Python教程
如有不足,欢迎指正。