📄 一句话概括
认出模式就等于认出了结构——实测 collections.abc 里有 53 个抽象基类,每个都是一块路标。
📝 本节和前面几节的关系
6.9 讲模式是什么,这一节讲怎么用模式读别人的代码。
一、路标的作用
读陌生的类库,最怕的是【不知道从哪看起】。
一旦认出模式,结构就露出来了:看到 Iterable 你就知道该实现 __iter__。
不用读实现——这就是 6.9 说的【思想集】在起的作用。
二、实测标准库里的路标
collections.abc 里有 53 个抽象基类。
实测五个:Iterable(list 是)、Sized(dict 是)、Mapping(dict 是)、Sequence(tuple 是)、Callable(函数是)。
这五个名字就是五块路标——看到名字就知道该实现哪几个方法。
三、正确的阅读顺序
先认模式,再看实现。 反过来会被细节淹掉:一个模块三千行,你从第一行读起,读到一半就迷路了。 具体做法:先看它继承了什么、实现了哪些特殊方法——那几行就把结构说完了。
四、顺带的好处
写自己的类时,主动符合这些路标——用户就不用读你的实现。
实测:自己写的类实现 __iter__ 和 __len__ 之后,for、sum、list 全都能用(6.11 会看到)。
所以路标是双向的:读别人的时候用,写自己的时候立。
五、动手 Demo:设计模式是类库探险的路标
数一数 standard library 里有多少抽象基类。 再验证几个常见类型各符合哪块路标。
import collections.abc as abc
print(len([n for n in dir(abc) if not n.startswith("_")]))
print(isinstance([], abc.Iterable))
print(isinstance({}, abc.Mapping))
print(isinstance((1,), abc.Sequence))
print(isinstance(len, abc.Callable))
实跑输出:
--------------------------------------------------------------------
设计模式是类库探险的路标
--------------------------------------------------------------------
读别人的类库时,**认出模式就等于认出了结构。**实测标准库里的对应:
collections.abc 里的抽象基类 53 个
前三个 ABCMeta/AsyncGenerator/AsyncIterable
路标(抽象基类) 实测 说明
-------------------------------------------------
Iterable(迭代器模式) 是 list 能 for
Sized 是 dict 有 len
Mapping(映射) 是 dict 是映射
Sequence 是 tuple 是序列
Callable 是 函数能调用
**这条路标的价值:看到 `Iterable` 你就知道该实现 `__iter__`,**
**不用去读它的实现——这正是 6.9 说的【思想集】在起的作用。**
**所以读类库的顺序是:先认模式,再看实现;反过来会被细节淹掉。**
实测:collections.abc 里 53 个抽象基类;list 是 Iterable、dict 是 Mapping、tuple 是 Sequence、函数是 Callable。
看到名字就知道该实现哪几个方法——所以读类库要先认模式再看实现。
30 秒实验
- 挑一个你不熟的库,先找它继承了哪些抽象基类。
- 用
isinstance验证几个内置类型各符合哪些路标。
常见误区
- 以为模式要背完才能读代码。认出一块路标就够走一段。
- 以为路标只用来读。写自己的类时立路标,别人才好读你。
自测三问(点开对答案)
1. 路标的作用是什么? —— 认出一块抽象基类就知道该实现哪几个方法,不用读实现——先认模式再看实现。 2. 实测 `collections.abc` 里有多少个抽象基类? —— 53 个;实测 list 是 Iterable、dict 是 Mapping、tuple 是 Sequence、函数是 Callable。 3. 为什么说路标是双向的? —— 读别人的时候靠它认结构;写自己的类时主动实现这些协议,别人也就不用读你的实现。- ☐ 下一节(6.11 扩展到各个领域的思想的重用)
相关笔记
- 设计模式是优秀的设计思想集 — 模式是什么
- 扩展到各个领域的思想的重用 — 再往外扩一层
- ⌨️ 编程原理 · 索引 — 接口与抽象
- 🧩 面向对象是怎样工作的 · 索引