# Python singledispatch 泛型函数 —— 根据类型自动选择实现 # 替代 isinstance 链,实现类似"重载"的效果,代码更整洁 from functools import singledispatch, singledispatchmethod from collections.abc import Iterable, Mapping, Sequence import numbers # 1. 单分派基础用法 @singledispatch def format_value(value): return f"未知类型: {type(value).__name__}" @format_value.register(int) def _(v): return f"整数: {v:,}" @format_value.register(float) def _(v): return f"浮点数: {v:.2f}" @format_value.register(str) def _(v): return f"字符串: '{v}'" @format_value.register(list) def _(v): return f"列表(len={len(v)}): {v[:3]}..." @format_value.register(bool) def _(v): return f"布尔: {'真' if v else '假'}" @format_value.register(type(None)) def _(v): return "空: None" for val in [1234567, 3.14159, "Hello", [1,2,3,4], True, None]: print(format_value(val)) # 2. singledispatchmethod —— 方法级分派 class DataProcessor: @singledispatchmethod def process(self, data): raise TypeError(f"不支持: {type(data).__name__}") @process.register(int) def _(self, data): return data * 2 @process.register(str) def _(self, data): return data.upper() @process.register(list) def _(self, data): return [self.process(item) for item in data] @process.register(dict) def _(self, data): return {k: self.process(v) for k, v in data.items()} p = DataProcessor() print("\n方法分派:", p.process(42), p.process("hello")) print("列表:", p.process([1, "a", 3])) # 3. 基于 ABC 的分派 @singledispatch def analyze(obj): return f"未知: {type(obj).__name__}" @analyze.register(numbers.Integral) def _(obj): return f"整型数: {'偶' if obj % 2 == 0 else '奇'}, 值={obj}" @analyze.register(Iterable) def _(o): return f"可迭代: {list(o)[:5]}..." @analyze.register(Mapping) def _(o): return f"映射: 键={list(o.keys())[:3]}" print("\nABC分派:", analyze(42), analyze([1,2,3]), analyze({"a":1})) # 4. 替代 isinstance 链 def process_old(v): if isinstance(v, int): return v + 1 elif isinstance(v, str): return v[::-1] elif isinstance(v, list): return len(v) elif isinstance(v, dict): return sum(v.values()) else: return v @singledispatch def process_new(v): return v @process_new.register(int) def _(v): return v + 1 @process_new.register(str) def _(v): return v[::-1] @process_new.register(list) def _(v): return len(v) @process_new.register(dict) def _(v): return sum(v.values()) for val in [42, "hello", [1,2,3], {"a":10,"b":20}, 3.14]: print(f" {type(val).__name__}: 旧={process_old(val)}, 新={process_new(val)}") # 5. 多个类型注册同一实现 def register_multiple(registry_func, *types): def decorator(func): for typ in types: registry_func.register(typ)(func) return func return decorator @singledispatch def safe_convert(value): return value @register_multiple(safe_convert, int, float) def _(v): return float(v) @register_multiple(safe_convert, str, bytes) def _(v): return str(v).strip() for val in [10, 3.14, " hello ", b"data"]: print(f" {type(val).__name__:8} -> {safe_convert(val)!r}")