← [ BACK_TO_NOTES ]

鸭子类型 (Duck Typing)

鸭子类型按行为能力而非名义类型协作;在 Python 中与特殊方法、Protocol 静态检查形成互补。

#concept #evergreen #dev #python #javascript #python

[!info] related notes

鸭子类型 (Duck Typing)

这个概念为什么出现

框架与库常说:“给我一个 file-like / iterable / awaitable 就行”。调用方不关心它是不是某个基类的子类,只关心能不能协作。这就是鸭子类型:

若走起来像鸭子、叫起来像鸭子,就当鸭子用。

[!abstract] 一句话理解 鸭子类型以运行时行为能力决定能否协作,而不是以名义继承身份;Python 用协议与特殊方法把它变成语言习惯。

最小可运行示例

先把示例放进业务场景,再看代码:

场景:导出服务接受任何“能提供只读行迭代”的来源

# duck_typing_export.py
# 业务意图:export_lines 不要求具体类,只要可迭代文本行。
# 教学点:
# - 面向协议而非基类;
# - list 与自定义对象都能协作;
# - 缺少协议则运行时失败。

from collections.abc import Iterable, Iterator


def export_lines(lines: Iterable[str]) -> str:
    # 业务:把多行正文合并为导出文本。
    return "\n".join(line.rstrip("\n") for line in lines)


class TicketLog:
    def __init__(self, rows: list[str]) -> None:
        self._rows = rows

    def __iter__(self) -> Iterator[str]:
        return iter(self._rows)


def main() -> None:
    print(export_lines(["a", "b"]))
    print(export_lines(TicketLog(["t1", "t2"])))


if __name__ == "__main__":
    main()

建议运行:

python duck_typing_export.py

期望输出:

a
b
t1
t2

结合场景再看三个关注点

  1. Iterable[str] 注解表达静态契约,不会在运行时自动验证每个元素是 str。\
  2. 自定义类实现返回迭代器的 iter,无需继承 Iterable;仍需保证产出符合业务约定的文本行。\
  3. 静态检查可用 Protocol 提前抓缺口(见专篇)。

核心概念与准确模型

维度鸭子类型名义类型
判断行为/结构声明的继承/实现
时刻使用行为时体现,类型检查器可提前辅助可在静态检查或运行时身份检查中体现
Python协议、dunderABCs 可名义可虚拟

Python 中的落点:

  • 特殊方法协议(容器、上下文、异步)
  • collections.abc
  • typing.Protocol(静态结构类型)

边界情况与反直觉行为

  1. 错误发现偏晚:缺方法到调用才炸。
  2. 同名不同义:都有 read 但语义不同。
  3. 过度鸭子让可读性下降——公开 API 仍要文档化协议。
  4. hasattr/callable 只能检查有限的形状,不能证明签名、返回值、异常或副作用符合协议;runtime_checkable Protocol 也不验证完整行为。
  5. Python 的 iter 还支持旧式 getitem 序列协议;运行时可迭代不等于一定通过 isinstance(x, Iterable) 或静态 Iterable 类型检查。\

常见误区

[!warning] 常见误区:动态语言所以不用类型 错误理解:鸭子类型排斥标注。
正确模型:运行时鸭子 + 静态 Protocol/注解可并存。

工程实践

  • 文档写清最小协议(“需要 __iter__ 产出 str”)。
  • 边界可检查关键方法,但真正契约仍需按使用方式测试;不能把方法同名当作语义相同。\
  • 公共库优先小协议,避免强迫继承框架基类。

本节总结

鸭子类型是 Python 协作的默认文化。用协议思考,用特殊方法实现,用 Protocol/测试加固。

自测题

  1. 鸭子类型与 isinstance 强制基类有何不同?
  2. 如何降低“用时才发现缺方法”的风险?
参考答案
  1. 鸭子类型按需要的行为协作;强制某具体基类通常按继承身份筛选。但 isinstance 也可由 ABC 的虚拟注册/结构钩子或 runtime_checkable Protocol 扩展,不总是纯名义判断。\
  2. Protocol/类型检查、契约测试、文档化最小方法集。

延伸阅读与资料来源

资料类型支撑内容
Glossary – duck-typing术语官方定义
typing.Protocol文档静态结构类型
创建于 2026/4/1 更新于 2026/10/6
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本