0. 一句话定位
| 维度 | 内容 |
|---|---|
| 作用对象 | 函数 |
| 使用场景 | 多态分发 |
| 来源 | 标准库 functools.singledispatch |
| 语法形式 | @singledispatch + @func.register(type) |
1. 做什么
根据第一个参数的运行时类型选择注册实现;无匹配时走默认(被 @singledispatch 装饰的函数体)。
2. 重点参数
| 参数 | 类型 | 默认值 | 作用 | 配置建议 |
|---|---|---|---|---|
func |
callable | — | 默认实现 | 作为 @singledispatch 的直接目标 |
type |
type / callable | — | 注册分支 | @f.register(int) 或 @f.register 装饰下一函数 |
singledispatchmethod(3.8+)用于类方法的第一参数为 self 之外的分派,另见标准库文档。
3. 最小可运行示例
1 | from functools import singledispatch |
1 | Received an integer: 39 |
4. 常见变体
注册抽象基类
1 | from collections.abc import Sequence |
查看已注册类型:display_info.registry
5. 适用 / 不适用
适用
- 同一操作名对不同输入类型有不同逻辑(序列化、格式化、相等比较)
- 避免长链
isinstance
不适用
- 多分派(多个参数类型组合)→ 需
multipledispatch等第三方库 - 子类优先级:更具体类型应后注册或显式注册,避免被 ABC 抢先
6. 易踩坑
- 只分派第一个参数;其余参数不参与选择
- 默认实现应处理未知类型或明确抛错
- 注册函数名可任意(常用
_),不影响分派
7. 近邻替代
| 替代 | 何时用 |
|---|---|
isinstance 分支 |
分支少、无扩展需求 |
multipledispatch |
多参数类型组合分派 |