- 第01课:初识 Python
- 第02课:第一个 Python 程序
- 第03课:Python 语言元素之变量
- 第04课:Python 语言元素之运算符
- 第05课:分支结构
- 第06课:循环结构
- 第07课:分支和循环结构的应用
- 第08课:常用数据结构之列表
- 第09课:常用数据结构之元组
- 第10课:常用数据结构之字符串
- 第11课:常用数据结构之集合
- 第12课:常用数据结构之字典
- 第13课:函数和模块
- 第14课:函数的应用
- 第15课:函数使用进阶
- 第16课:函数的高级应用
- 第17课:面向对象编程入门
- 第18课:面向对象编程进阶
- 第19课:面向对象编程应用
- 第20课:Python 标准库初探
- 第21课:文件读写和异常处理
- 第22课:对象的序列化和反序列化
- 第23课:用 Python 读写 CSV 文件
- 第24课:用 Python 读写 Excel 文件-1
- 第25课:用 Python 读写 Excel 文件-2
- 第26课:用 Python 操作 Word 文件和 PowerPoint
- 第27课:用 Python 操作 PDF 文件
- 第28课:用 Python 处理图像
- 第29课:用 Python 发送邮件和短信
- 第30课:正则表达式的应用
- 第31课:网络数据采集概述
- 第32课:用 Python 获取网络资源
- 第33课:用 Python 解析 HTML 页面
- 第34课:Python 中的并发编程-1
- 第35课:Python 中的并发编程-2
- 第36课:Python 中的并发编程-3
- 第37课:并发编程在爬虫中的应用
- 第38课:抓取网页动态内容
- 第39课:爬虫框架 Scrapy 简介
- 第40课:关系型数据库和 MySQL 概述
- 第41课:SQL 详解之 DDL
- 第42课:SQL 详解之 DML
- 第43课:SQL 详解之 DQL
- 第44课:SQL 详解之 DCL
- 第45课:索引
- 第46课:视图 + 函数 + 过程
- 第47课:MySQL 新特性
- 第48课:Python 程序接入 MySQL 数据库
第20课:Python 标准库初探
第20课:Python标准库初探
Python语言最可爱的地方在于它的标准库和三方库实在是太丰富了,日常开发工作中的很多任务都可以通过这些标准库或者三方库直接解决。下面我们先介绍Python标准库中的一些常用模块,后面的课程中再陆陆续续为大家介绍Python常用三方库的用途和用法。
base64 - Base64编解码模块
Base64是一种基于64个可打印字符来表示二进制数据的方法。由于$log _{2}64=6
Base64是一种基于64个可打印字符来表示二进制数据的方法。由于$log _{2}64=6$,所以Base64以6个比特(二进制位,可以表示0或1)为一个单元,每个单元对应一个可打印字符。对于3字节(24比特)的二进制数据,我们可以将其处理成对应于4个Base64单元,即3个字节可由4个可打印字符来表示。Base64编码可用来作为电子邮件的传输编码,也可以用于其他需要将二进制数据转成文本字符的场景,这使得在XML、JSON、YAML这些文本数据格式中传输二进制内容成为可能。在Base64中的可打印字符包括A-Z
、a-z
、0-9
,这里一共是62个字符,另外两个可打印符号通常是+
和/
,=
用于在Base64编码最后进行补位。
A-Z
、a-z
、0-9
,这里一共是62个字符,另外两个可打印符号通常是+
和/
,=
用于在Base64编码最后进行补位。关于Base64编码的细节,大家可以参考《Base64笔记》一文,Python标准库中的base64
模块提供了b64encode
和b64decode
两个函数,专门用于实现Base64的编码和解码,下面演示了在Python的交互式环境中执行这两个函数的效果。
>>> import base64
>>>
>>> content = 'Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.'
>>> base64.b64encode(content.encode())
b'TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4='
>>> content = b'TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4='
>>> base64.b64decode(content).decode()
'Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.'
collections - 容器数据类型模块
collections
模块提供了诸多非常好用的数据结构,主要包括:
namedtuple
:命令元组,它是一个类工厂,接受类型的名称和属性列表来创建一个类。deque
:双端队列,是列表的替代实现。Python中的列表底层是基于数组来实现的,而deque
底层是双向链表,因此当你需要在头尾添加和删除元素是,deque
会表现出更好的性能,渐近时间复杂度为$O(1)$。Counter
:dict
的子类,键是元素,值是元素的计数,它的most_common()
方法可以帮助我们获取出现频率最高的元素。Counter
和dict
的继承关系我认为是值得商榷的,按照CARP原则,Counter
跟dict
的关系应该设计为关联关系更为合理。OrderedDict
:dict
的子类,它记录了键值对插入的顺序,看起来既有字典的行为,也有链表的行为。defaultdict
:类似于字典类型,但是可以通过默认的工厂函数来获得键对应的默认值,相比字典中的setdefault()
方法,这种做法更加高效。
下面是在Python交互式环境中使用namedtuple
创建扑克牌类的例子。
>>> from collections import namedtuple
>>>
>>> Card = namedtuple('Card', ('suite', 'face'))
>>> card1 = Card('红桃', 5)
>>> card2 = Card('草花', 9)
>>> card1
Card(suite='红桃', face=5)
>>> card2
Card(suite='草花', face=9)
>>> print(f'{card1.suite}{card1.face}')
红桃5
>>> print(f'{card2.suite}{card2.face}')
草花9
下面是使用Counter
类统计列表中出现次数最多的三个元素的例子。
from collections import Counter
words = [
'look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes',
'the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around',
'the', 'eyes', "don't", 'look', 'around', 'the', 'eyes',
'look', 'into', 'my', 'eyes', "you're", 'under'
]
counter = Counter(words)
# 打印words列表中出现频率最高的3个元素及其出现次数
for elem, count in counter.most_common(3):
print(elem, count)
hashlib - 哈希函数模块
哈希函数又称哈希算法或散列函数,是一种为已有的数据创建“数字指纹”(哈希摘要)的方法。哈希函数把数据压缩成摘要,对于相同的输入,哈希函数可以生成相同的摘要(数字指纹),需要注意的是这个过程并不可逆(不能通过摘要计算出输入的内容)。一个优质的哈希函数能够为不同的输入生成不同的摘要,出现哈希冲突(不同的输入产生相同的摘要)的概率极低, MD5 、SHA家族 就是这类好的哈希函数。
说明:在2011年的时候,RFC 6151中已经禁止将MD5用作密钥散列消息认证码,这个问题不在我们讨论的范围内。
Python标准库的hashlib
模块提供了对哈希函数的封装,通过使用md5
、sha1
、sha256
等类,我们可以轻松的生成“数字指纹”。举一个简单的例子,用户注册时我们希望在数据库中保存用户的密码,很显然我们不能将用户密码直接保存在数据库中,这样可能会导致用户隐私的泄露,所以在数据库中保存用户密码时,通常都会将密码的“指纹”保存起来,用户登录时通过哈希函数计算密码的“指纹”再进行匹配来判断用户登录是否成功。
import hashlib
# 计算字符串"123456"的MD5摘要
print(hashlib.md5('123456'.encode()).hexdigest())
# 计算文件"Python-3.7.1.tar.xz"的MD5摘要
hasher = hashlib.md5()
with open('Python-3.7.1.tar.xz', 'rb') as file:
data = file.read(512)
while data:
hasher.update(data)
data = file.read(512)
print(hasher.hexdigest())
说明:很多网站在下载链接的旁边都提供了哈希摘要,完成文件下载后,我们可以计算该文件的哈希摘要并检查它与网站上提供的哈希摘要是否一致(指纹比对)。如果计算出的哈希摘要与网站提供的并不一致,很有可能是下载出错或该文件在传输过程中已经被篡改,这时候就不应该直接使用这个文件。
heapq - 堆排序模块
heapq
模块实现了堆排序算法,如果希望使用堆排序,尤其是要解决TopK问题(从序列中找到K个最大或最小元素),直接使用该模块即可,代码如下所示。
import heapq
list1 = [34, 25, 12, 99, 87, 63, 58, 78, 88, 92]
# 找出列表中最大的三个元素
print(heapq.nlargest(3, list1))
# 找出列表中最小的三个元素
print(heapq.nsmallest(3, list1))
list2 = [
{'name': 'IBM', 'shares': 100, 'price': 91.1},
{'name': 'AAPL', 'shares': 50, 'price': 543.22},
{'name': 'FB', 'shares': 200, 'price': 21.09},
{'name': 'HPQ', 'shares': 35, 'price': 31.75},
{'name': 'YHOO', 'shares': 45, 'price': 16.35},
{'name': 'ACME', 'shares': 75, 'price': 115.65}
]
# 找出价格最高的三只股票
print(heapq.nlargest(3, list2, key=lambda x: x['price']))
# 找出持有数量最高的三只股票
print(heapq.nlargest(3, list2, key=lambda x: x['shares']))
itertools - 迭代工具模块
itertools
可以帮助我们生成各种各样的迭代器,大家可以看看下面的例子。
import itertools
# 产生ABCD的全排列
for value in itertools.permutations('ABCD'):
print(value)
# 产生ABCDE的五选三组合
for value in itertools.combinations('ABCDE', 3):
print(value)
# 产生ABCD和123的笛卡尔积
for value in itertools.product('ABCD', '123'):
print(value)
# 产生ABC的无限循环序列
it = itertools.cycle(('A', 'B', 'C'))
print(next(it))
print(next(it))
print(next(it))
print(next(it))
random - 随机数和随机抽样模块
这个模块我们之前已经用过很多次了,生成随机数、实现随机乱序和随机抽样,下面是常用函数的列表。
getrandbits(k)
:返回具有k
个随机比特位的整数。randrange(start, stop[, step])
:从range(start, stop, step)
返回一个随机选择的元素,但实际上并没有构建一个range
对象。randint(a, b)
:返回随机整数N
满足a <= N <= b
,相当于randrange(a, b+1)
。choice(seq)
:从非空序列seq
返回一个随机元素。 如果seq
为空,则引发IndexError
。choices(population, weight=None, *, cum_weights=None, k=1)
:从population
中选择替换,返回大小为k
的元素列表。 如果population
为空,则引发IndexError
。shuffle(x[, random])
:将序列x
随机打乱位置。sample(population, k)
:返回从总体序列或集合中选择k
个不重复元素构造的列表,用于无重复的随机抽样。random()
:返回[0.0, 1.0)
范围内的下一个随机浮点数。expovariate(lambd)
:指数分布。gammavariate(alpha, beta)
:伽玛分布。gauss(mu, sigma)
/normalvariate(mu, sigma)
:正态分布。paretovariate(alpha)
:帕累托分布。weibullvariate(alpha, beta)
:威布尔分布。
os.path - 路径操作相关模块
os.path
模块封装了操作路径的工具函数,如果程序中需要对文件路径做拼接、拆分、获取以及获取文件的存在性和其他属性,这个模块将会非常有帮助,下面为大家罗列一些常用的函数。
dirname(path)
:返回路径path
的目录名称。exists(path)
:如果path
指向一个已存在的路径或已打开的文件描述符,返回True
。getatime(path)
/getmtime(path)
/getctime(path)
:返回path
的最后访问时间/最后修改时间/创建时间。getsize(path)
:返回path
的大小,以字节为单位。如果该文件不存在或不可访问,则抛出OSError
异常。isfile(path)
:如果path
是普通文件,则返回True
。isdir(path)
:如果path
是目录(文件夹),则返回True
。join(path, *paths)
:合理地拼接一个或多个路径部分。返回值是path
和paths
所有值的连接,每个非空部分后面都紧跟一个目录分隔符 (os.sep
),除了最后一部分。这意味着如果最后一部分为空,则结果将以分隔符结尾。如果参数中某个部分是绝对路径,则绝对路径前的路径都将被丢弃,并从绝对路径部分开始连接。splitext(path)
:将路径path
拆分为一对,即(root, ext)
,使得root + ext == path
,其中ext
为空或以英文句点开头,且最多包含一个句点。
uuid - UUID生成模块
uuid
模块可以帮助我们生成全局唯一标识符(Universal Unique IDentity)。该模块提供了四个用于生成UUID的函数,分别是:
uuid1()
:由MAC地址、当前时间戳、随机数生成,可以保证全球范围内的唯一性。uuid3(namespace, name)
:通过计算命名空间和名字的MD5哈希摘要(“指纹”)值得到,保证了同一命名空间中不同名字的唯一性,和不同命名空间的唯一性,但同一命名空间的同一名字会生成相同的UUID。uuid4()
:由伪随机数生成UUID,有一定的重复概率,该概率可以计算出来。uuid5()
:算法与uuid3
相同,只不过哈希函数用SHA-1取代了MD5。
由于uuid4
存在概率型重复,那么在真正需要全局唯一标识符的地方最好不用使用它。在分布式环境下,uuid1
是很好的选择,因为它能够保证生成ID的全局唯一性。下面是在Python交互式环境中使用uuid1
函数生成全局唯一标识符的例子。
>>> import uuid
>>> uuid.uuid1().hex
'622a8334baab11eaaa9c60f81da8d840'
>>> uuid.uuid1().hex
'62b066debaab11eaaa9c60f81da8d840'
>>> uuid.uuid1().hex
'642c0db0baab11eaaa9c60f81da8d840'
简单的总结
Python标准库中有大量的模块,日常开发中有很多常见的任务在Python标准库中都有封装好的函数或类可供使用,这也是Python这门语言最可爱的地方。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论