常用的一些必备模块。如:
collections:【标准库】Python 增强数据类型,常用如 deque 双端队列,OrderedDict 有序字典,Counter 计数器operator:【标准库】标准运算符替代函数itertools:【标准库】一系列迭代功能的函数。返回Iterator,for迭代循环时才计算。functools:【标准库】高阶函数contextlib:将任意对象变为上下文对象,并支持with语句。queue:【标准库】一个同步的队列类celery:一个异步任务队列/作业队列,基于分布式消息传递。rq:简单的 Python 作业队列。heapq:【标准库】:堆队列算法,求前 n 个最大/最小的数字array:高效的数值数组dataclasses:数据类,python3.7 推出的,面向数据的思维,节省写__init__()等实例方法enum:【标准库】枚举类
概述
collections
collections:【标准库】Python 增强数据类型,常用如 deque 双端队列,OrderedDict 有序字典,Counter 计数器
defaultdict:带有默认值的字典,适合处理字典键值对deque:双端队列,用于快速插入和删除操作
deque 双端队列
- 可从头或尾部高效地添加或删除元素,方便实现队列与栈
- 队列:常用来传递任务和接收结果
- 任务的描述数据量要尽可能小,如发送一个处理日志文件的任务,不要发送几百 MB 的日志文件,而是发送文件的完整路径。
1 | from collections import deque |
OrderedDIct 有序字典
- 注意,
OrderedDict的 Key 会按照插入的顺序排列,不是 Key 本身排序:OrderedDict可以实现一个 FIFO(先进先出)的 dict,当容量超出限制时,先删除最早添加的 Key:
1 | from collections import OrderedDict |
Counter 计数器
- 统计元数个数
- 统计字符串中字符出现的次数
1 | from collections import Counter |
namedtuple
namedtuple:命名元组,通过属性访问元
1 | from collections import namedtuple |
defaultdict:默认值字典
- 在字典中如果使用的 key 不存在,就会抛出 KeyError 错误,假如我们希望在 key 不存在的时候,返回自定义的值时可使用 defaultdict。
- 除了在 Key 不存在时返回默认值,
defaultdict的其他行为跟dict是完全一样的。
1 | from collections import defaultdict |
operator
operator:【标准库】标准运算符替代函数
- Python 内置的操作符函数接口,定义了一些算术和比较内置操作的函数,基于 C,执行速度快。
1 | #内置函数 |
itertools
itertools:【标准库】一系列迭代功能的函数。返回Iterator,for迭代循环时才计算。
- 高效迭代器
1 | from itertools import combinations |
accumulate
accumulate(iterable[, func, *, initial=None]):列表的累积汇总
1 | list(itertools.accumulate([1,2,3,4,5],lambda x,y:x*y)) |
排列组合
1 | # 求列表或生成器中指定数目的元素不重复的所有组合 |
product
1 | def find_twelve(num_list1, num_list2, num_list3): |
1 | # 扁平化多层嵌套 |
chain
- 连接多个可迭代对象,便于合并数据
1 | from itertools import chain |
product:生成笛卡尔积combinations:生成元素组合permutations:生成排列
functools
functools:【标准库】高阶函数,函数操作的利器
- 高效处理函数操作,简化代码结构,常用于高阶函数或装饰器
1 | cached_property |
- partial:创建一个带默认参数的函数。
lru_cache:缓存函数结果reduce:执行累积计算
lru_cache
- 缓存函数结果,在后续调用相同的参数的该函数时,不会再执行,而是直接用结果。
- 对于计算量大 或 使用相同参数频繁调用的函数特别有用
- 缓存机制,加快数据的速度
1 |
|
1 | from functools import lru_cache |
1 | # 速度测试 |
contextlib
contextlib:将任意对象变为上下文对象,并支持with语句。
- 即可使用 with,不用担心资源没 close
- 易用的上下文管理器工具,通过生成器实现
1 | from contextlib import contextmanager |
1 | import contextlib |
queue
queue:【标准库】一个同步的队列类
- 常用于让多线程编程更安全
celery
celery:一个异步任务队列/作业队列,基于分布式消息传递。
- 简单、灵活、可靠的分布式系统,消息队列工具,用于处理实时数据及任务调度
rq
rq:简单的 Python 作业队列。
heapq
heapq:【标准库】:堆队列算法,求前 n 个最大/最小的数字
1 | import heapq |
array
array:高效的数值数组
dataclasses
#最佳实践
dataclasses:数据类,一个带有默认值的可变的 numedtuple。python3.7 推出的,面向数据的思维,节省写__init__()等实例方法
- 推荐使用它而不是 namedtuple
- 相比于普通 class:
- dataclass 通常不包含私有属性,数据可直接访问
- repr 通常有固定格式,会打印出类型名、属性名及对应的值
- 具有
__eq__和__hash__魔法方法 - 模式单一固定的构造方法。使用类型注解语法,生成一个实现了
__init__、__repr__、__cmp__等方法的 dataclass
- 相比于 enum:
- Enum 主要是将不可变的名称/值对包含在可迭代对象中
- dataclass:具有默认值的可变命名元组
- 继承:
dataclass装饰器会检查当前 class 的所有基类,如果发现一个 dataclass,就会把它的字段按顺序添加进当前的 class,随后再处理当前 class 的 field。所有生成的方法也将按照这一过程处理,因此如果子类中的 field 与基类同名,那么子类将会无条件覆盖基类。子类将会根据所有的 field 重新生成一个构造函数,并在其中初始化基类。
- dataclass 通常情况下是 unhashable 的,因为默认生成的
__hash__是None,所以不能用来做字典的 key,如果有这种需求,那么应该指定你的数据类为 frozen dataclass - 小心当你定义了和
dataclass生成的同名方法时会引发的问题 - 当使用可变类型(如 list)时,应该考虑使用
field的default_factory - 数据类的属性都是公开的,如果你有属性只需要初始化时使用而不需要在其他时候被访问,请使用
dataclasses.InitVar - 限制 hash:限制为不可变字段`field(hash=False)
- 显示限制的字段:
field(repr=Fase) - 比较限制:(在比较时排除这个字段):
field(compare=False) - list_1.remove(Test(name=’chen’)),当 Test 是 dataclasses 时,只要它的属性是一致的,就会认为是同一个
1 | from dataclasses import dataclass,field,fields |
__post_init__
- datacalss会先根据你定义的字段,自动生成一个标准的
__init__方法,这个方法只做一件事:把你传入的参数赋值给self。然后立即调用__post_init__ - 建议将所有复杂的初始化逻辑,写到
__post_init__中__init__:由dataclass 自动生成,进行数据绑定(将创建实例时传入的数据正确地绑定到实例的属性上)- dataclass 有什么(数据)?
__post_init__:初始化逻辑。在数据绑定完成后,执行所有必要的后续步骤。比如数据验证、调用其他方法等。- dataclass 做什么(操作)?
1 | from typing import Dict, Any, List |
field
举个例子,对于 list,当复制它时只是复制了一份引用,所以像 dataclass 里那样直接复制给实例的做法的危险而错误的,为了保证使用 list 时的安全性,应该这样做:
1 |
|
常用函数
1 | from dataclasses import asdict, astuple |
enum
enum:【标准库】枚举类
- 一种数据类型,列出所有可能的取值。常用做一系列常量的集中处理,如月份、颜色
- python3.4 及以上的版本才有
- 优点:
- 省内存:程序中是代码,内存中是 value,即数值,value:
1的占用比 name:red的少
- 省内存:程序中是代码,内存中是 value,即数值,value:
- 要求:
- 枚举类不能用来实例化对象,不可更改
- 成员变量不重复
- 成员变量值相同时,输出的结果都是前一个成员的
- 若要不能定义相同的成员值,可以用
@unique来修饰 - 不能用
=赋值,可以用 is 或 == 比较,但不能比较大小(IntEnum 时,INT 整数枚举可以相互比较) - Attention:两个地方写的相同代码的 Enum 类,导入后,
==比较的值不对,是多线程的坑还是它本身的坑?
1 | from enum import Enum |
1 | from enum import Enum,unique |
