《Python基础教程》第1章笔记👉https://blog.csdn.net/holeer/article/details/143052930
第10章 开箱即用
本章简要介绍模块的工作原理以及如何探索模块以获悉其提供的功能,然后概述标准库,重点是几个很有用的模块。
10.1 模块
10.1.1 模块就是程序
任何Python程序都可作为模块导入。假设你编写了一行程序print("Hello, world!")
,并将其保存在文件hello.py中,这个文件的名称(不包括扩展名.py)将成为模块的名称。
文件的存储位置也很重要。这里假设这个文件存储在目录C:\python
中。要告诉解释器去哪里查找这个模块,可执行如下命令:
>>> import sys
>>> sys.path.append('C:/python')
【注意】当你导入模块时,可能发现其所在目录中除源代码文件外,还新建了一个名为__pycache__
的子目录。这个目录包含处理后的文件(.pyc)。删除该目录不会有任何害处,因为必要时会重新创建它。
导入这个模块时,执行了其中的代码。但如果再次导入它,什么事情都不会发生。模块并不是用来执行操作(如打印文本)的,而是用于定义变量、函数、类等。鉴于定义只需做一次,因此导入模块多次和导入一次的效果相同。
10.1.2 模块是用来下定义的
模块在首次被导入程序时执行。模块像类一样,有自己的作用域。这意味着在模块中定义的类和函数以及对其进行赋值的变量都将成为模块的属性。
在模块中定义函数之后,可通过“模块名.函数名”的形式访问它。这样做主要是为了重用代码。
如果要在模块中添加测试代码,通常建议将其放在一个独立函数中,并使其在单独运行时(而不是导入时)执行。示例如下。
# hello4.py
def hello():print("Hello, world!")def test():hello()if __name__ == '__main__': test()
10.1.3 让模块可用
在10.1.1的示例中修改了sys.path。然而,通常你不想这样做。最理想的情况是,sys.path一开始就包含正确的目录(你的模块所在的目录)。为此有两种办法:将模块放在正确的位置;告诉解释器到哪里去查找。如果要让别人能够轻松地使用你的模块,那就是另外一码事了。Python打包技术一度日益复杂、各自为政,对于这个棘手的主题,建议参阅“Python打包用户指南”:packaging.python.org。
(1)将模块放在正确的位置
使用以下命令打印出sys.path中的所有位置:
>>> import sys, pprint
>>> pprint.pprint(sys.path)
输出中应该会包含一个site-packages目录。这个目录就是用来放置模块的。
(2)告诉解释器到哪里去查找
你还可以将模块所在的目录包含在环境变量PYTHONPATH
中。
此外,你还可使用路径配置文件。这些文件的扩展名为.pth,位于一些特殊目录中。有关这方面的详细信息,请参阅模块site的标准库文档。
10.1.4 包
为组织模块,可将其编组为包(package)。包其实就是一种特殊的模块,它可以包含其他模块。模块存储在扩展名为.py的文件中,而包则是一个目录。要被Python视为包,目录必须包含文件__init__.py
。要将模块加入包中,只需将模块文件放在包目录中即可。文件__init__.py
也是包的一个模块,且可以直接通过包名访问其中定义的东西。你还可以在包中嵌套其他包。
10.2 探索模块
探索模块是一种很有用的技能,因为在你的Python程序员职业生涯中,将遇到很多很有用的模块,而这里无法一一介绍。当前的标准库很大,足以编写专著来论述。每个新Python版本都新增了模块,通常还会对一些既有模块进行细微的修改和改进。
(1)模块包含什么
要探索模块,最直接的方式是使用Python解释器进行研究。为此,首先需要将模块导入。假设你听说有一个名为copy的标准模块,在将其导入后,你可以做一些事情。
①使用dir函数:dir(copy)
将列出模块所有的函数、类、变量等。要排除内部名称,请使用[n for n in dir(copy) if not n.startswith('_')]
。
②访问变量__all__
:这个变量用于定义模块的公有接口。具体而言,它告诉解释器从这个模块导入所有的名称意味着什么。因此,如果你使用代码from copy import *
,将只能得到copy.__all__
中列出的3个函数(Error, copy, deepcopy)。在编写模块时,这种设置也很有用。因为模块可能包含大量其他程序不需要的变量、函数和类,比较周全的做法是将它们过滤掉。
(2)使用help获取帮助
help函数可提供你通常需要的所有信息,如help(copy.copy)
。
(3)文档
文档字符串就是在函数开头编写的字符串,用于对函数进行说明,而函数的属性__doc__
可能包含这个字符串。你可以直接将其打印出来查看,如print(range.__doc__)
。
就学习Python编程而言,最有用的文档是“Python库参考手册”(https://docs.python.org/library),它描述了标准库中的所有模块。
(4)使用源代码
要学习Python,阅读源代码是除动手编写代码外的最佳方式。
实际阅读源代码应该不成问题,但源代码在哪里呢?一种快捷的方式是查看模块的特性__file__
,比如print(copy.__file__)
。
请注意,有些模块的源代码你完全无法读懂。它们可能是解释器的组成部分,还可能是使用C语言编写的。
10.3 标准库:一些深受欢迎的模块
在Python中,短语“开箱即用”指的是Python丰富的标准库。
10.3.1 sys
模块sys让你能够访问与Python解释器紧密相关的变量和函数,如下表所示。
表10-2 模块sys中一些重要的函数和变量
函数/变量 | 描述 |
---|---|
argv | 命令行参数,包括脚本名 |
exit([arg]) | 退出当前程序,可通过可选参数指定返回值或错误消息 |
modules | 一个字典,将模块名映射到加载的模块 |
path | 一个列表,包含要在其中查找模块的目录的名称 |
platform | 一个平台标识符,如win32 |
stdin | 标准输入流 |
stdout | 标准输出流 |
stderr | 标准错误流 |
sys.argv[0]
为Python脚本名,sys.argv[1]
为第1个命令行参数。
函数sys.exit()
可接收一个整数,指出程序是否成功。在大多数情况下,使用默认值0(表示成功)即可。也可向它提供一个字符串,这个字符串将成为错误消息,对用户找出程序终止的原因很有帮助。
Python从sys.stdin
获取输入,并将输出打印到sys.stdout
。
10.3.2 os
模块os让你能够访问多个操作系统服务,如下表所示。模块pathlib
则提供了一个面向对象的路径操作接口。
表10-3 模块os中一些重要的函数和变量
函数/变量 | 描述 |
---|---|
environ | 包含环境变量的映射 |
system(command) | 在子shell中执行操作系统命令 |
sep | 路径中使用的分隔符 |
pathsep | 分隔不同路径的分隔符 |
linesep | 行分隔符(‘\n’、‘\r’或’\r\n’) |
urandom(n) | 返回n个字节的强加密随机数据 |
Windows特有的函数os.startfile
可以用于启动外部程序,如os.startfile(r'C:\Program Files (x86)\Mozilla Firefox\firefox.exe')
。
模块webbrowser
可用于打开指定的网页,如webbrowser.open('http://www.python.org')
。
10.3.4 集合、堆和双端队列
(1)集合
集合是由内置类set实现的。可使用序列(或其他可迭代对象)来创建集合,也可使用花括号显式地指定。注意,不能仅使用花括号来创建空集合,因为这将创建一个空字典。集合的基本方法包括add
和remove
。要计算两个集合的并集,可对其中一个集合调用方法union
,也可使用运算符|。示例代码如下。
>>> set(range(10))
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
>>> a = {1, 2, 3}
>>> b = {2, 3, 4}
>>> a.union(b)
{1, 2, 3, 4}
>>> a | b
{1, 2, 3, 4}
>>> a.intersection(b)
{2, 3}
>>> c = a & b # 交集
>>> c
{2, 3}
>>> c = a & b
>>> c.issubset(a)
True
>>> c <= aTrue
>>> c.issuperset(a)
False
>>> a - b
{1}
>>> a ^ b
{1, 4}
集合是可变的,因此不能用作字典中的键。另一个问题是,集合只能包含不可变的值,因此不能包含其他集合。
(2)堆
堆是一种优先队列。实际上,Python没有独立的堆类型,而只有一个包含一些堆操作函数的模块。这个模块名为heapq
。必须使用列表来表示堆对象本身。
(3)双端队列
在需要按添加元素的顺序进行删除时,双端队列很有用。在模块collections中,包含类型deque
以及其他几个集合类型。
10.3.5 time
函数time.sleep
让解释器等待指定的秒数。
10.3.6 random
表10-8 模块random中一些重要的函数
函数 | 描述 |
---|---|
random() | 返回一个(0,1]的随机实数 |
uniform(a, b) | 返回一个(a,b]的随机实数 |
randrange([start], stop, [step]) | 从range(start, stop, step)中随机地选择一个数 |
choice(seq) | 从序列seq中随机地选择一个元素 |
shuffle(seq[, random]) | 就地打乱序列seq |
sample(seq, n) | 从序列seq中随机地选择n个值不同的元素 |
10.3.7 shelve
函数shelve.open
将一个文件名(建议以.dat结尾)作为参数,并返回一个Shelf对象,供你用来存储数据。你可像操作普通字典那样操作它(只是键必须为字符串),操作完毕(并将所做的修改存盘)时,可调用其方法close
。
10.3.8 re
模块re提供了对正则表达式的支持。
1.正则表达式是什么
正则表达式是可匹配文本片段的模式。最简单的正则表达式为普通字符串,与它自己匹配。
(1)通配符
句点表示除换行符外的任何字符,因此正则表达式’.ython’与字符串’python’和’jython’都匹配。
(2)转义字符
如果要匹配字符串’python.org’,由于句点已经被用作通配符,因此正则表达式应为’python\.org’,这里有两层转义。还有一种处理是使用原始字符串,即r’python.org’。
(3)字符集
方括号表示字符集。‘[pj]ython’与’python’和’jython’都匹配。’[a-z]‘与a~z的任何字母都匹配。’[a-zA-Z0-9]'则匹配由1个大写字母、1个小写字母和1个数字组成的字符串。要指定排除字符集,可在开头添加一个^
字符,例如'[^abc]'
与除a、b和c外的其他任何字符都匹配。
(4)或运算和子模式
如果只想匹配字符串’python’和’perl’,则所需模式为’python|perl’,其中’|'为或运算符。子模式位于圆括号内,比如’p(ython|erl)'与前面的模式等效。
(5)可选模式和重复模式
通过在子模式后面加上问号,可将其标记为可选的。重复模式的标记语法如下:
- (pattern)*:pattern可重复0、1或多次。
- (pattern)+:pattern可重复1或多次。
- (pattern){m,n}:模式可重复m~n次
(6)字符串的开头和末尾
用脱字符(‘^’)表示字符串的开头,美元符号($)表示末尾。
2.模块re的内容
表10-9 模块re中一些重要的函数
函数 | 描述 |
---|---|
compile(pattern) | 根据包含正则表达式的字符串创建模式对象 |
search(pattern, string) | 在字符串中查找模式 |
match(pattern, string) | 在字符串开头匹配模式 |
split(pattern, string[,maxsplit=0]) | 根据模式来分割字符串 |
findall(pattern, string) | 返回一个列表,其中包含字符串中所有与模式匹配的子串 |
sub(pat, repl, string[, count=0]) | 将字符串中与模式pat匹配的子串都替换为repl |
escape(string) | 对字符串中所有的正则表达式特殊字符都进行转义 |
调用search、match等函数时,如果提供的是用字符串表示的正则表达式,都必须在内部将它们转换为模式对象。通过使用函数compile对正则表达式进行转换后,每次使用它时都无需再进行转换。模式对象也有搜索/匹配方法,因此re.search(pat, string)
(其中pat是一个使用字符串表示的正则表达式)等价于pat.search(string)
(其中pat是使用compile创建的模式对象)。
6.模板系统示例
模板(template) 是一种文件,可在其中插入具体的值来得到最终的文本。在模板处理中需要用到以下工具:
- 使用正则表达式来匹配字段并提取其内容。
- 使用
eval
来计算表达式字符串,并提供包含作用域的字典。 - 使用
exec
来执行语句字符串(和其他语句),并将模板的作用域存储到字典中。 - 使用
re.sub
将被处理的字符串替换为计算得到的结果。
代码清单10-11 一个模板系统
# templates.pyimport fileinput, refield_pat = re.compile(r'\[(.+?)\]')scope = {}def replacement(match):code = match.group(1)try:return str(eval(code, scope))except SyntaxError:exec(code, scope)return ''lines = []
for line in fileinput.input():lines.append(line)
text = ''.join(lines)print(field_pat.sub(replacement, text))
代码清单10-12 示例模板(listing10-12.txt)
[x = 2]
[y = 3]
The sum of [x] and [y] is [x + y].
执行命令python templates.py listing10-12.txt
,期望输出应该为:The sum of 2 and 3 is 5.
。
10.3.9 其他有趣的标准模块
csv:轻松读写CSV文件。
datetime:支持特殊的日期和时间对象。
num:枚举类型。
hashlib:可用于在加密和安全领域计算大型文本文件的签名。