面向对象并非一套固定范式,而是一种理解软件结构与变化的思维方式。本系列文章不从语法或设计模式出发,而从“使用”、“协作”与“演化”的视角,重新审视 Python 中的对象、接口与多态。这里的 OOP,不是对类型的崇拜,而是对行为边界、使用约定与长期可维护性的认真对待。
在序言 | 在Python中重新理解面向对象
第一部分|对象与封装:从边界思维到约定思维
对象并非因类而存在,而是因使用而成立。本部分从“对象是什么”出发,重新理解封装在 Python 中的真实含义:它不是强制隔离的技术手段,而是对使用者的行为约定。对象的边界,不由语法决定,而由责任与使用方式塑造。
第 1 章 存在即对象
1.1 从“一切皆对象”谈起
1.2 对象先于类型而存在
1.3 对象不等于实例
1.4 类、实例与对象的关系重构
1.5 对象的能力来源:属性访问机制
1.6 对象的意义在于使用
第 2 章 封装是使用约定
2.1 传统封装的边界模型
2.2 Python 的封装观:约定优于强制
2.3 状态与行为的分离
2.4 公有属性作为接口承诺
2.5 私有命名的语义表达
2.6 封装与可演化设计
2.7 何时需要更强的封装
第二部分|接口观:使用方式即契约
接口并不是预先设计出来的抽象结构,而是在使用过程中逐渐稳定的行为契约。本部分从属性访问这一最小单元入手,说明接口如何在真实调用中形成、演化并被验证。接口的价值,不在声明本身,而在是否支撑长期稳定的使用。
第 3 章 属性即接口
3.1 接口的本质:从声明到使用
3.2 属性访问:接口的最小单元
3.3 属性的进化之路:从字段到接口
3.4 描述符协议:属性接口的底层保障
3.5 属性接口的设计原则
3.6 工程实践中的典型属性接口模式
第 4 章 接口产生于使用
4.1 接口并非设计产物
4.2 使用方式决定接口形态
4.3 调用方视角下的接口
4.4 接口稳定性与实现自由度
4.5 接口隔离源于使用克制(ISP 视角)
4.6 接口演化与向后兼容
4.7 使用即测试的接口验证
4.8 可迭代协议与上下文管理接口
第三部分|多态的来源:行为,而非身份
多态常被误解为类型层级的产物,但在 Python 中,它更多发生在调用是否成功的瞬间。本部分将多态还原为“行为一致性”的问题,并将失败路径纳入设计视野,说明异常、EAFP 等机制如何共同构成可协作系统的基础。
第 5 章 多态发生在调用点
5.1 传统多态:基于类型分派
5.2 Python 的多态:基于调用成功
5.3 调用点决定多态语义
5.4 同一调用,不同对象
5.5 多态与接口稳定性
5.6 运行时多态的优势
第 6 章 行为一致性构成多态
6.1 行为一致性的含义
6.2 语义一致而非实现一致
6.3 方法名并非多态核心
6.4 属性访问中的多态
6.5 协作语境中的行为一致性
6.6 行为一致性的实践保障
第 7 章 失败路径也是多态
7.1 失败作为正常分支
7.2 Python 的异常语义
7.3 多态中的失败一致性
7.4 EAFP 与 LBYL 的设计立场
7.5 明确失败条件的接口设计
7.6 失败多态的实际应用
第四部分|继承的降级:从层级到组合
继承并非错误,但往往被过度使用。本部分刻意“降低继承的地位”,转而强调协议、组合与能力拼装的设计方式。通过对多继承、Mixin 与策略组合的分析,展示 Python 中更具演化弹性的结构选择。
第 8 章 继承不是类型建模
8.1 继承的传统语义
8.2 Python 中继承的真实用途
8.3 继承带来的隐性耦合
8.4 何时不应使用继承
8.5 继承作为最后手段
8.6 继承的替代方案
第 9 章 协议优于继承
9.1 协议的本质含义
9.2 鸭子类型的协议实践
9.3 非显式接口的力量
9.4 协议与接口稳定性
9.5 typing.Protocol 的静态支持
9.6 魔法方法与运算符重载接口
第 10 章 组合优先于继承
10.1 组合的基本思想
10.2 行为组合而非类型扩展
10.3 委托模式的自然表达
10.4 组合带来的演化自由
10.5 组合与测试友好性
10.6 组合与策略模式
第 11 章 多继承是能力组合
11.1 多继承的常见误解
11.2 MRO 的语义保障
11.3 多继承中的职责拆分
11.4 Mixin 的正确使用方式
11.5 何时避免多继承
11.6 受约束的多继承实践
第五部分|抽象与演化:面向变化的设计思想
抽象并不是设计的起点,而是经验的沉淀。本部分围绕“变化”展开,讨论封装、抽象与重构在演化过程中的真实角色。设计不追求一次到位,而是在不断调整中逐渐逼近稳定结构。
第 12 章 抽象源于使用经验
12.1 抽象不是起点
12.2 从具体使用中提炼抽象
12.3 抽象的稳定性问题
12.4 过早抽象的风险
12.5 抽象的重构时机
12.6 渐进式抽象的模式
第 13 章 封装服务于演化
13.1 封装与变化的关系
13.2 可替换实现的边界
13.3 演化中的接口稳定
13.4 封装失败的常见模式
13.5 为未来变化预留空间
13.6 封装的演进策略
13.7 单一职责原则(SRP)在 Python 中的实践
第 14 章 演化优先于设计
14.1 设计不是一次性行为
14.2 小步演化的价值
14.3 重构作为设计手段
14.4 设计滞后的合理性
14.5 演化中的技术债控制
14.6 演化驱动设计的实践模式
第六部分|Python 语言立场:超越传统 OOP
Python 并不完全遵循传统面向对象语言的路径,而是更重视运行期决策、可读性与协作表达。本部分站在语言立场上,重新审视显式性、动态绑定与异步接口,说明 Python 如何以自己的方式延展 OOP 的边界。
第 15 章 显式是一种设计责任
15.1 显式的真实含义
15.2 可读性与意图表达
15.3 明确优于巧妙
15.4 显式并非冗余
15.5 显式接口的长期价值
15.6 显式设计的具体实践
第 16 章 运行期决策优先
16.1 编译期思维的局限
16.2 Python 的运行期能力
16.3 动态绑定与延迟决策
16.4 运行期失败的可控性
16.5 运行期即设计现场
16.6 运行期决策的实际应用
16.7 元类与类级设计
第 17 章 可读性是接口语义的一部分
17.1 接口不仅是技术契约
17.2 可读性影响使用方式
17.3 命名即接口
17.4 代码风格与设计哲学
17.5 人是接口的最终使用者
17.6 自解释接口与文档化实践
17.7 实践:编写自解释的接口
第 18 章 异步接口与协作
18.1 异步接口的设计原则
18.2 async/await 与运行期多态
18.3 异步资源管理与上下文协议
18.4 异步接口的组合与可替换性
18.5 异步接口的可读性与文档化
18.6 异步接口的错误处理模式
结语|面向使用而非形式
面向对象的价值,不在于是否遵循某种范式,而在于是否帮助我们构建可理解、可演化的系统。Python 提供的不是严格的规则,而是一组倾向:重视使用、尊重协作、接受变化。真正成熟的设计,往往并不复杂,只是对这些倾向保持足够的自觉。