# Python singledispatch 泛型函数 —— 根据类型自动选择实现# 替代 isinstance 链实现类似重载的效果代码更整洁from functools import singledispatch, singledispatchmethodfrom collections.abc import Iterable, Mapping, Sequenceimport numbers# 1. 单分派基础用法singledispatchdef 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 空: Nonefor val in [1234567, 3.14159, Hello, [1,2,3,4], True, None]:print(format_value(val))# 2. singledispatchmethod —— 方法级分派class DataProcessor:singledispatchmethoddef process(self, data):raise TypeError(f不支持: {type(data).__name__})process.register(int)def _(self, data): return data * 2process.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 的分派singledispatchdef 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 1elif isinstance(v, str): return v[::-1]elif isinstance(v, list): return len(v)elif isinstance(v, dict): return sum(v.values())else: return vsingledispatchdef process_new(v): return vprocess_new.register(int)def _(v): return v 1process_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 funcreturn decoratorsingledispatchdef safe_convert(value): return valueregister_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 , bdata]:print(f {type(val).__name__:8} - {safe_convert(val)!r})
Pythonsingledispatch泛型函数
# Python singledispatch 泛型函数 —— 根据类型自动选择实现# 替代 isinstance 链实现类似重载的效果代码更整洁from functools import singledispatch, singledispatchmethodfrom collections.abc import Iterable, Mapping, Sequenceimport numbers# 1. 单分派基础用法singledispatchdef 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 空: Nonefor val in [1234567, 3.14159, Hello, [1,2,3,4], True, None]:print(format_value(val))# 2. singledispatchmethod —— 方法级分派class DataProcessor:singledispatchmethoddef process(self, data):raise TypeError(f不支持: {type(data).__name__})process.register(int)def _(self, data): return data * 2process.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 的分派singledispatchdef 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 1elif isinstance(v, str): return v[::-1]elif isinstance(v, list): return len(v)elif isinstance(v, dict): return sum(v.values())else: return vsingledispatchdef process_new(v): return vprocess_new.register(int)def _(v): return v 1process_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 funcreturn decoratorsingledispatchdef safe_convert(value): return valueregister_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 , bdata]:print(f {type(val).__name__:8} - {safe_convert(val)!r})