Chapter 5
第5章Python标准库
章节主张
第5章Python标准库这一章真正要建立的,不是孤立知识点,而是围绕“标准库是解决日常编程问题的常备箱、环境与工具链先于语法细节、函数与模块是从会写到会组织的分水岭”形成一套能反复练习、能迁移到真实任务里的 Python 学习路径。
中文释读
读 第5章Python标准库 时,不要只把它当作语法或模块说明书。更有价值的读法,是问自己:这一章解决了我在编程、科学计算或数据分析流程中的哪个瓶颈?
这本书的强项在于把工具、基础语法、科学计算库和案例工作流连成一条线。章节页因此会把原书内容翻译成“知识点 -> 操作动作 -> 易错边界 -> 迁移练习”的学习结构。
本章知识路线
关键论据
- 导入sys模块: 1.命令行参数 命令行参数 (Command Line Arguments)是在命令行执行程序时,向程序添加的参数信息。
- 对于Python,一个带命令行参数的调用方式如下: 其中,foo.py、arg1、arg2是传给Python的三个命令行参数。
- 命令行参数可以使用sys模块的变量sys.argv查看。
- 例如,有一个脚本hello_world.py,负责打印程序运行时sys.argv包含的信息: 在命令行运行脚本hello_world.py: 程序打印了以下两行内容: 第一行内容是sys.argv的值,它是一个由命令行参数组成的列表。
- 由于命令行参数只有脚本名,因此,sys.argv的值为: 如果在运行脚本时,加上更多的命令行参数: sys.argv是一个将命令行参数按照空格分开得到的字符串列表。
行动清单
- 先用最小代码样例跑通本章核心知识点。
- 把本章知识点接到一个真实小任务上,而不只停留在示例。
- 记录本章最容易报错的边界条件和调试方式。
- 复盘:这一章内容如何进入自己的长期 Python 学习系统。
本章图版学习路径
图版按知识点分组,适合拿来做复现、迁移和复盘练习,不只是“看一眼效果”。
源章节深读
5.1 系统相关:sys模块
这节解决什么问题:这节要解决的不是背下“5.1 系统相关:sys模块”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。
怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“5.1 系统相关:sys模块”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。
常见错误:常见误区是只记住 API 或代码片段,却没理解 5.1 系统相关:sys模块 背后的对象模型、输入输出和适用边界。
sys模块是与系统相关的标准库模块。导入sys模块: 1.命令行参数 命令行参数 (Command Line Arguments)是在命令行执行程序时,向程序添加的参数信息。对于Python,一个带命令行参数的调用方式如下: 其中,foo.py、arg1、arg2是传给Python的三个命令行参数。命令行参数可以使用sys模块的变量sys.argv查看。例如,有一个脚本hello_world.py,负责打印程序运行时sys.argv包含的信息: 在命令行运行脚本hello_world.py: 程序打印了以下两行内容: 第一行内容是sys.argv的值,它是一个由命令行参数组成的列表。由于命令行参数只有脚本名,因此,sys.argv的值为: 如果在运行脚本时,加上更多的命令行参数: sys.argv是一个将命令行参数按照空格分开得到的字符串列表。其中,123并不会被解析为数字。再次修改hello_world.py,让它输出第二个命令行参数的值: 执行脚本: 参数默认按照空格进行分割。不过,输入一个带有空格的参数,如Zhang San,因为空格的存在,程序只会输出“Zhang”: 为了让参数中能包含空格,可以使用一对引号将参数包含起来,在解析时,引号中的部分会被当作一个整体来处理: 如果运行时不给程序传入任何命令行参数,sys.argv中只有一个元素sys.argv[0],索引位置1不存在,抛出异常: 为了处理这个问题,可以修改程序,对sys.argv中元素的个数进行判断,使得程序在没有参数时,输出“Hello World!”: 运行结果: 2.系统路径 变量sys.path可以查看Python搜索模块的路径和查找顺序,不同操作系统的路径和顺序会有一定的差异。在Windows系统下,搜索路径类似于:
5.2 与操作系统进行交互:os模块
这节解决什么问题:这节要解决的不是背下“5.2 与操作系统进行交互:os模块”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。
怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“5.2 与操作系统进行交互:os模块”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。
常见错误:常见误区是只记住 API 或代码片段,却没理解 5.2 与操作系统进行交互:os模块 背后的对象模型、输入输出和适用边界。
os模块是与操作系统进行交互的标准库模块。导入os模块: 不建议使用“fromos import *”的形式,因为这样可能会导致内置函数被覆盖。 1.文件相关的操作 os模块包含一些与文件操作相关的函数。比如,获取当前工作目录: IPython的魔术命令%pwd与此功能一致。 工作目录 (Working Directory)表示当前程序运行的位置,可以基于此位置使用相对路径,如访问文件、调用自定义模块等。一般来说,打开程序的位置就是工作目录的位置。 当前工作目录的符号: 对于文件系统来说,通常用“.”来表示当前工作目录的缩写,而“..”表示当前目录的父目录缩写。可以用缩写“~”表示当前用户的 家目录 (Home Directory)。家目录是多用户操作系统上包含特定用户文件的系统目录,其具体位置和名称与操作系统有关。 一般来说,Windows 7及以上系统的家目录形式为: 而Linux系统下则是: Mac系统下则是: os.listdir()函数可以用来查看一个文件夹的所有文件和子文件夹名称,不过不包括子文件夹中的目录: 利用这个函数返回的结果,可以判断一个文件是否在某个指定的目录中。例如,先新建一个文件: 然后判断该文件是否在当前目录中: os.rename()函数可以用来重命名文件: os.remove()函数可以用来删除文件: os模块中与文件相关的常用函数总结如下。 ●os.getcwd():获取当前工作目录。 ●os.chdir(path):改变当前工作目录。
5.3 正则表达式:re模块
这节解决什么问题:这节要解决的不是背下“5.3 正则表达式:re模块”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。
怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“5.3 正则表达式:re模块”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。
常见错误:常见误区是只记住 API 或代码片段,却没理解 5.3 正则表达式:re模块 背后的对象模型、输入输出和适用边界。
re模块是与正则表达式相关的标准库模块。 正则表达式 (Regular Expression)是一种强大的字符串匹配模式,通常使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。 1.正则表达式的规则 常用的正则表达式匹配规则见表5-1。 表5-1 常用的正则表达式匹配规则 (续) 在正则表达式规则中,部分字符有特殊的含义。当需要匹配这些有特殊含义的字符时,通常需要用反斜杠进行转义处理,如\[、\]、\{、\}、\(、\)、\.。除此之外,字符串中常用的转义字符,如\a、\b、\f、\n、\t、\v、\x、\\等在正则表达式中都可以被使用和匹配。正则表达式的例子如下。 ●表达式:ca*t,a*表示匹配0个或者多个a,因此匹配的字符串有ct、cat、caat等。 ●表达式:ab\d|ac\d,匹配ab或者ac加数字的组合,因此匹配的字符串有ab1、ac8、ab5、ac9等。 ●表达式:(ab)?c,中间括号中的ab是一个整体,因此匹配的字符串为c和ab。 ●表达式:(ab|cd)e,括号部分匹配ab或者cd,因此匹配的字符串为abe和cde。 ●表达式:[^a-q]bd,中括号匹配非a~q的任意字符,因此匹配的字符串有6bd、zbd等。 ●表达式:\d{3}-?\d{8},匹配3个数字加8个数字的组合,中间的横线可以省略,因此匹配的字符串有010-12345678、01099999999等。 2.re模块的使用 导入re模块: (1)re.match()函数 re.match()函数对字符串的开头进行匹配: 其中,参数pattern是正则表达式,string是要匹配的字符串。如果字符串的开头符合正则表达式的规则,该函数会返回一个Match对象,否则返回None。例如,定义一个匹配连续数字的表
5.4 日期时间相关:datetime模块
这节解决什么问题:这节要解决的不是背下“5.4 日期时间相关:datetime模块”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。
怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“5.4 日期时间相关:datetime模块”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。
常见错误:常见误区是只记住 API 或代码片段,却没理解 5.4 日期时间相关:datetime模块 背后的对象模型、输入输出和适用边界。
datetime模块是处理时间和日期的标准库模块,它提供了一些处理时间和日期的基本操作。导入datetime模块: 在下文中,用dt代替datetime模块的名称。 1.date对象 dt.date()函数可以产生一个有年月日信息的date对象,其用法为: date对象需要指定年月日,例如: 分别表示2008年9月25日和2007年9月25日。日期可以打印出来: 可以调用date对象的.strftime()方法将日期转化为特定格式: 日期和时间的控制符可以查看表5-2。当天的日期可以用dt.date.today()来得到: 2.timedelta对象 两个日期可以相减,从而查看两个日期相差多久,例如,2008年9月25日和2007年9月25日正好相差了一年,即366天(2008年是闰年): 两个date对象相减返回的是一个时间间隔timedelta对象。 时间间隔也可以用dt.timedelta()函数构造,参数依次表示天、秒、毫秒、微秒、分、时、周,如果不指定默认为0: 3.time对象 dt.time()函数可以产生一个time对象,其用法为: 不指定的参数默认为0,例如: time对象的默认输出格式为: 输出格式同样可以用.strftime()方法来改变: 由于time对象不涉及具体的日期,所以它不支持减法操作。
5.5 读写JSON数据:json模块
这节解决什么问题:这节要解决的不是背下“5.5 读写JSON数据:json模块”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。
怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“5.5 读写JSON数据:json模块”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。
常见错误:常见误区是只记住 API 或代码片段,却没理解 5.5 读写JSON数据:json模块 背后的对象模型、输入输出和适用边界。
json模块是处理JSON数据的标准库模块。 JSON (JavaScript Object Notation)是一种轻量级的数据交换格式,既易于人们阅读和编写,也易于机器解析和生成。 1.JSON的基本结构 JSON有以下几种基本结构。 1)object:JSON对象,用大括号表示,形式为(数据是无序的): 2)pair:JSON键值对,形式为: 3)array:JSON数组,用中括号表示,形式为(数据是有序的): 4)value:JSON值,可以是以下几种类型。 ●object:JSON对象。 ●string:字符串。 ●array:JSON数组。 ●number:数字。 ●true、false、null:特殊值。 按照上述规则,一个合法的JSON对象可以是类似这样的文本: 2.JSON数据与Python对象的转换 Python标准库提供了json模块来处理JSON数据: 将上面的JSON对象存入一个字符串: 用json.loads()函数从字符串中读取这个JSON对象: print显示长字典不太美观,可以借助pprint模块来打印这个对象:
5.6 文件模式匹配:glob模块
这节解决什么问题:这节要解决的不是背下“5.6 文件模式匹配:glob模块”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。
怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“5.6 文件模式匹配:glob模块”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。
常见错误:常见误区是只记住 API 或代码片段,却没理解 5.6 文件模式匹配:glob模块 背后的对象模型、输入输出和适用边界。
glob模块是与文件模式匹配相关的标准库模块,提供了方便的文件模式匹配方法: 假设当前工作目录的文件结构如下: 用glob.glob()函数进行匹配,可以得到当前目录下所有以“.txt”结尾的文件: 其中,星号“*”用来匹配不包括路径分隔符在内的任意长字符。因此,文件夹中的两个“.txt”没有被匹配。如果想匹配文件夹中的.txt文件,可以使用这样的形式: 第一个星号“*”用来匹配文件夹名,第二个星号“*”用来匹配.txt文件的文件名,中间用斜杠“/”分开。在Windows系统下,文件分隔符是反斜杠“\”,不过,Python能自动根据操作系统的不同将“/”解析为对应的文件分隔符,所以在编程时,可以统一使用“/”作为分隔符。 一般来说,glob.glob()函数支持以下格式的语法。 ●“*”:匹配单个或多个字符,除了路径分隔符。 ●“?”:匹配任意单个字符。 ●“[seq]”:匹配指定范围内的单个字符,如[0-9]匹配单个数字。 ●“[!seq]”:匹配非指定范围内的单个字符,如[!0-9]匹配非数字的单个字符。 ●如果要匹配“*”和“?”本身,可以使用“[*]”和“[?]”来转义。 例如,匹配所有单个数字命名的文件: 如果想要匹配非当前目录的文件,只需要将指定的目录名写入即可。例如,匹配当前目录的父目录下的.txt文件: 对于其他目录,可以考虑输入目录的绝对路径。值得注意的是,glob.glob()函数不能自动解析家目录的符号“~”。如果想要匹配当前目录以及子目录下的所有“.txt”文件,可以用:
5.7 高级文件操作:shutil模块
这节解决什么问题:这节要解决的不是背下“5.7 高级文件操作:shutil模块”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。
怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“5.7 高级文件操作:shutil模块”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。
常见错误:常见误区是只记住 API 或代码片段,却没理解 5.7 高级文件操作:shutil模块 背后的对象模型、输入输出和适用边界。
shutil模块是一个提供高级文件操作的标准库模块。os模块支持一些简单的文件删除和重命名操作,对于更为高级的文件操作,需要使用shutil模块。导入这两个模块: 1.文件的复制 在当前目录下新建一个文件: 复制文件可以使用: 该函数将源文件复制到目标地址: 如果目标地址中间的文件夹不存在,会抛出异常: 2.文件夹的复制 为了复制文件夹,可以使用os.renames()函数重命名文件,将刚才的这两个文件转移到一个文件夹中: 与os.rename()函数不同,os.renames()函数在遇到不存在的文件夹时会自动创建这个文件夹。这样,通过重命名操作,将两个文件转移到了文件夹test_dir中。 复制文件夹可以使用: 该函数将源文件夹复制到目标位置: 这样,test_dir中的内容就被复制到了新文件夹test_dir_copy中: 3.非空文件夹的删除 os.removedirs()函数不能删除非空文件夹: 删除一个非空文件夹可以使用shutil.rmtree()函数: 4.文件夹的移动 shutil.move()函数可以整体移动文件夹,与os.renames()函数的功能类似,因为移动一个文件夹相当于对这个文件夹进行重命名。 math模块是Python与数学计算相关的标准库模块。导入math模块:
5.9 随机数:random模块
这节解决什么问题:这节要解决的不是背下“5.9 随机数:random模块”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。
怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“5.9 随机数:random模块”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。
常见错误:常见误区是只记住 API 或代码片段,却没理解 5.9 随机数:random模块 背后的对象模型、输入输出和适用边界。
random模块是Python中与随机数相关的标准模块。导入random模块: random.randint()函数可以产生一个随机整数,其用法为: 该函数产生a~b(包括a和b)的一个随机整数: random.randrange()函数也可以产生一个随机整数,其用法为: 该函数三个参数的使用与切片的规则类似,即包括start不包括stop;step是间隔,默认为1;省略start和step时,start默认为0: random.random()函数可以生成一个0~1的随机数: random.choice()函数可以从一个序列中随机选择一个元素: random.shuffle()函数可以将序列中元素的顺序打乱: random.sample()函数可以从序列中不放回地随机采样元素,如从0~9中采样3个元素: 除此之外,random模块还可以产生一些满足特定概率分布的随机数。
5.10 路径操作:pathlib模块
这节解决什么问题:这节要解决的不是背下“5.10 路径操作:pathlib模块”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。
怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“5.10 路径操作:pathlib模块”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。
常见错误:常见误区是只记住 API 或代码片段,却没理解 5.10 路径操作:pathlib模块 背后的对象模型、输入输出和适用边界。
Python 3提供了一个新的模块pathlib,提供了Path类型来进行更方便的路径操作。导入pathlib模块: 定义一个路径对象,指定当前目录: 获得当前目录下所有的“txt”文件,可以不再依赖glob模块,而是直接调用.glob()方法: 路径的连接也可以不再使用os.path.join(),而可以用“/”运算替代: 文件是否存在可以调用.exists()方法: 打开文件可以调用.open()方法: .is_dir()方法判断是否为文件夹: .iterdir()方法遍历当前文件夹: Python 2与Python 3的区别之pathlib模块 :Python 2一般用os.path模块进行路径操作;Python 3额外提供了pathlib模块进行路径操作,更加方便。
5.11 网址URL相关:urllib模块
这节解决什么问题:这节要解决的不是背下“5.11 网址URL相关:urllib模块”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。
怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“5.11 网址URL相关:urllib模块”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。
常见错误:常见误区是只记住 API 或代码片段,却没理解 5.11 网址URL相关:urllib模块 背后的对象模型、输入输出和适用边界。
Python标准库中,与网址URL相关的模块是urllib模块。在urllib模块中,主要包含几个常用的子模块。本节将学习以下两个模块的使用。 ●urllib.request:打开和读取网页URL相关的操作。 ●urllib.parse:解析网页URL。 导入这两个子模块: 最常见的操作是访问一个网页。urllib.request模块提供了urlopen()函数,用来访问网页,常见的用法如下: urlopen()函数返回的网页对象与文件类似,可以支持.read()方法或者.readlines()方法从对象中读取数据,并且与文件使用类似,使用了上下文管理器的with语句,保证连接在出现异常时正确关闭。 Python 2和Python 3的区别之urllib模块 :Python 2有urllib与urllib2两个模块来处理网页URL的相关操作;Python 3则改为使用urllib.request模块和urllib.parse模块,Python 2中的urllib.urlopen()函数被移除,urllib2.urlopen()函数则被重命名为Python 3中的urllib.request.urlopen()函数。 另一个比较常见的操作是将网页URL的内容直接存储到某个文件中,该操作需要使用urllib.request模块的urlretrieve()函数,该函数接受一个URL和文件名,将该URL链接的内容存储到指定的文件中: 网页URL通常需要满足某种特定的格式,其参数通常在URL的问号后传入,并以符号“&”和符号“=”分割来表示不同的参数对。urllib模块提供了一些处理URL格式问题的工具。例如,使用urllib.parse的urlencode()的函数将一个字典转为URL串的格式: 这里,
5.12 实例:使用标准库实现桌面墙纸下载
这节解决什么问题:这节要解决的不是背下“5.12 实例:使用标准库实现桌面墙纸下载”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。
怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“5.12 实例:使用标准库实现桌面墙纸下载”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。
常见错误:常见误区是只记住 API 或代码片段,却没理解 5.12 实例:使用标准库实现桌面墙纸下载 背后的对象模型、输入输出和适用边界。
本节将介绍一个小实例,利用标准库实现一个桌面墙纸自动下载的程序。墙纸下载的网站为 该网址是一个缓存Bing首页图片的网址。为了使用程序访问这个网址,先定义一个URL链接对象: 为了访问这个网址,需要调用urllib模块: 部分网址会有一些简单的反爬虫策略,需要在使用urllib.request模块时,传入一些访问网页必需的参数,如网页的headers。urllib.request模块提供了Request对象来实现headers的传入: 利用该对象,可以访问这个网址,并设置超时为20s: urllib模块返回的结果是一个bytes对象,而不是str,因此需要调用.decode()方法将其转换为字符串: 对于得到的网页内容字符串,可以使用正则表达式提取其中墙纸图片的URL链接: 在下载图片之前,首先利用pathlib模块创建一个文件夹存储图片: 再利用正则表达式,可以从图片URL中解析出图片的名称: 最后将图片存储到指定位置: 由于Bing每天都会更新墙纸,为了每次能更新前一天的数据,可以考虑将图片网址的URL改为使用每天的日期计算得到: 最后,考虑到可能需要获取其他日期的墙纸,在脚本模式下,可以利用sys.argv接受一个指定参数,从多少天前开始进行循环下载。此外,每次下载完图片后,需要利用time模块和random模块随机停止几秒,防止反爬虫机制的触发。 综合之前的实现,一个完整程序“wallpaper.py”的实现代码如下: 利用该程序下载最近5天的墙纸:
5.13 本章学习笔记
这节解决什么问题:这节要解决的不是背下“5.13 本章学习笔记”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。
怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“5.13 本章学习笔记”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。
常见错误:常见误区是只记住 API 或代码片段,却没理解 5.13 本章学习笔记 背后的对象模型、输入输出和适用边界。
本章对Python常用标准库的使用进行了简单介绍。Python标准库模块提供了很多方便的工具和功能,掌握常用标准库的使用能让编程事半功倍。 学完本章,读者应该做到: ●掌握如何使用sys模块处理命令行参数。 ●掌握如何使用os模块进行系统相关的操作。 ●掌握如何使用re模块进行正则表达式匹配。 ●知道如何使用datetime模块进行与时间日期相关的操作。 ●掌握如何使用json模块处理JSON文件。 ●知道如何使用shutil模块进行高级文件操作。 ●掌握如何使用math模块进行数学函数的计算。 ●掌握如何使用random模块进行随机数的生成。 ●掌握如何使用pathlib模块进行路径的操作。 ●掌握如何使用urllib模块进行URL访问的操作。 1.本章新术语 本章涉及的新术语见表5-3。 表5-3 本章涉及的新术语 2.本章新函数 本章涉及的新函数见表5-4。 表5-4 本章涉及的新函数
辨析题:如果你只会照抄 第5章Python标准库 里的例子,却无法换一个输入自己写出来,真正缺的是什么?
多数时候缺的不是记忆,而是对象模型、输入输出边界和操作顺序的理解。把知识点换到新输入上依然能运行,才算真的进入了自己的系统。