"当鸭子游泳像鸭、叫声像鸭——它就是鸭。" Python用动态类型重构了面向对象核心,让继承链流淌如活水。
继承机制:C3算法的拓扑魔术
class A: pass
class B(A): pass
class C(A): pass
class D(B, C): pass # 钻石继承结构
print(D.mro())
# 输出:[D, B, C, A, object] - 宽度优先的C3线性化
- MRO动态生成:基于继承图拓扑排序
super()
本质:super(D, self).method()
等价于self.__class__.mro()[1].method()
- 混入类(Mixin):无继承关系的横向功能注入
鸭子类型:无契约的多态革命
class Duck:
def quack(self): print("嘎嘎")
class Person:
def quack(self): print("伪鸭叫")
def in_forest(obj):
obj.quack() # 不检查类型,只认行为
in_forest(Duck()) # 嘎嘎
in_forest(Person()) # 伪鸭叫
- 多态不依赖继承关系
- 协议接口:实现
__iter__
即为可迭代对象 - 内置函数如
len()
依赖对象实现__len__
协议
抽象基类:动态语言的静态约束
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self): pass # 强制接口
class Circle(Shape):
def area(self): # 必须实现
return 3.14 * self.radius**2
collections.abc
定义容器接口(如Iterable, Sequence)- 注册虚拟子类:
Sequence.register(tuple)
__subclasshook__
实现自定义类型检查
实战演绎:标准库中的继承艺术
案例 |
继承策略 |
多态体现 |
Django Model |
模型字段层级继承 |
save()方法的多态调用 |
异常体系 |
Exception层级捕获 |
捕获基类即捕获所有子类异常 |
io模块 |
TextIOWrapper多重继承 |
同时继承BufferedIOBase和TextIOBase |
pathlib.Path |
纯虚基类PathBase |
不同操作系统返回Path子类实例 |
思考题:当鸭子类型遭遇@overload
类型提示,动态多态与静态约束能否共存?Python 3.12的typing.override
装饰器正试图给出答案——这是语言的进化还是对哲学初衷的背叛?