Python Protocol 通过鸭子类型和结构声明实现结构化类型,不依赖继承,仅要求对象具备指定属性和方法签名,由类型检查器静态验证,不参与运行时。

Python 的 Protocol 通过“鸭子类型 + 结构声明”的方式实现结构化类型,不依赖继承,只关注对象是否具备指定的属性和方法签名。
用 Protocol 定义结构契约
Protocol 是一个类型提示工具,用于描述“只要满足某些接口,就视为该类型”。它本身不参与运行时检查,仅在类型检查器(如 mypy、pylance)中生效。
- 定义时使用
class MyProtocol(Protocol):,内部只写方法签名和属性注解,不写实现 - 方法无需
def ...: pass,但需有完整类型标注(含返回值) - 支持可选成员(用
Optional[...]或Union[...])、类变量、实例变量、重载方法等
让普通类“隐式实现”Protocol
只要一个类拥有 Protocol 所要求的所有属性和方法,且签名兼容,类型检查器就认为它实现了该 Protocol——无需显式继承或注册。
- 例如 Protocol 要求
def render(self) -> str:,那么任意带同签名render方法的类都自动适配 - 参数名可不同(如
self可写成obj),但位置、数量、类型、返回值必须一致 - 多余的方法或属性不影响匹配,Protocol 只做“最小契约”校验
配合泛型和类型变量增强表达力
Protocol 支持泛型,能精确描述结构化类型的参数关系,比如容器类或回调函数的输入输出一致性。
立即学习“Python免费学习笔记(深入)”;
- 用
class SupportsAdd[T](Protocol): def __add__(self: T, other: T) -> T: ...表达“可自加且返回同类型” - 结合
TypeVar(如Self或绑定类型变量)可约束方法返回值与调用者类型一致 - 常见标准 Protocol 如
Iterable[T]、Mapping[K, V]都是泛型结构化类型
与 ABC 和抽象基类的区别
Protocol 是静态的、结构性的;ABC 是动态的、名义性的。前者看“像什么”,后者看“是不是”。
- ABC 需显式继承(
class C(AbcClass):)或调用register(),运行时可检测isinstance - Protocol 不改变运行时行为,也不影响
isinstance或issubclass,纯为类型安全服务 - 二者可共存:一个类既继承 ABC,又自然满足某个 Protocol,类型检查器会同时认可










