白学这么多年 Python?连泛型函数都不会写?
泛型 , 如果你尝过java , 应该对他不陌生吧 。 但你可能不知道在 Python 中(3.4+ ) , 也可以实现 简单的泛型函数 。
在Python中只能实现基于单个(第一个)参数的数据类型来选择具体的实现方式 , 官方名称 是 single-dispatch
。 你或许听不懂 , 说人话 , 就是可以实现第一个参数的数据类型不同 , 其调用的函数也就不同 。
singledispatch
是 PEP443 中引入的 , 如果你对此有兴趣 , PEP443 应该是最好的学习文档:
它使用方法极其简单 , 只要被singledispatch
装饰的函数 , 就是一个single-dispatch
的泛函数(generic functions
) 。
- 单分派:根据一个参数的类型 , 以不同方式执行相同的操作的行为 。
- 多分派:可根据多个参数的类型选择专门的函数的行为 。
- 泛函数:多个函数绑在一起组合成一个泛函数 。
from functools import singledispatch@singledispatchdef age(obj):print('请传入合法类型的参数!')@age.register(int)def _(age):print('我已经{}岁了 。 '.format(age))@age.register(str)def _(age):print('I am {} years old.'.format(age))age(23)# intage('twenty three')# strage(['23'])# list
执行结果我已经23岁了 。 I am twenty three years old.请传入合法类型的参数!
说起泛型 , 其实在 Python 本身的一些内建函数中并不少见 , 比如 len()
,iter()
, copy.copy()
, pprint()
等你可能会问 , 它有什么用呢?实际上真没什么用 , 你不用它或者不认识它也完全不影响你编码 。
我这里举个例子 , 你可以感受一下 。
【白学这么多年 Python?连泛型函数都不会写?】大家都知道 , Python 中有许许多的数据类型 , 比如 str , list ,dict ,tuple 等 , 不同数据类型的拼接方式各不相同 , 所以我这里我写了一个通用的函数 , 可以根据对应的数据类型对选择对应的拼接方式拼接 , 而且不同数据类型我还应该提示无法拼接 。 以下是简单的实现 。
def check_type(func):def wrapper(*args):arg1, arg2 = args[:2]if type(arg1) != type(arg2):return '【错误】:参数类型不同 , 无法拼接!!'return func(*args)return wrapper@singledispatchdef add(obj, new_obj):raise TypeError@add.register(str)@check_typedef _(obj, new_obj):obj += new_objreturn obj@add.register(list)@check_typedef _(obj, new_obj):obj.extend(new_obj)return obj@add.register(dict)@check_typedef _(obj, new_obj):obj.update(new_obj)return obj@add.register(tuple)@check_typedef _(obj, new_obj):return (*obj, *new_obj)print(add('hello',', world'))print(add([1,2,3], [4,5,6]))print(add({'name': 'wangbm'}, {'age':25}))print(add(('apple', 'huawei'), ('vivo', 'oppo')))# list 和 字符串 无法拼接print(add([1,2,3], '4,5,6'))
输出结果如下hello, world[1, 2, 3, 4, 5, 6]{'name': 'wangbm', 'age': 25}('apple', 'huawei', 'vivo', 'oppo')【错误】:参数类型不同 , 无法拼接!!
如果不使用singledispatch 的话 , 你可能会写出这样的代码 。def check_type(func):def wrapper(*args):arg1, arg2 = args[:2]if type(arg1) != type(arg2):return '【错误】:参数类型不同 , 无法拼接!!'return func(*args)return wrapper@check_typedef add(obj, new_obj):if isinstance(obj, str) :obj += new_objreturn objif isinstance(obj, list) :obj.extend(new_obj)return objif isinstance(obj, dict) :obj.update(new_obj)return objif isinstance(obj, tuple) :return (*obj, *new_obj)print(add('hello',', world'))print(add([1,2,3], [4,5,6]))print(add({'name': 'wangbm'}, {'age':25}))print(add(('apple', 'huawei'), ('vivo', 'oppo')))# list 和 字符串 无法拼接print(add([1,2,3], '4,5,6'))
输出如下hello, world[1, 2, 3, 4, 5, 6]{'name': 'wangbm', 'age': 25}('apple', 'huawei', 'vivo', 'oppo')【错误】:参数类型不同 , 无法拼接!!
推荐下我本人原创的 《PyCharm 中文指南》电子书 , 内含大量(300张)的图解 , 制作之精良 , 值得每个 Python 工程师点个收藏 。地址是:
文章插图
- 基站|华为一手养肥的这家小巨人,真这么值钱吗?
- oppo reno|到OPPO线下体验了一番,终于知道Reno7系列为什么卖得这么好了
- 联想|联想当初反对国企采购电脑预装国产系统,为何这么做?担心美国断芯?
- 双十一|联想和华为的差距到底在哪里?为什么联想的存在感这么弱!
- iOS|iOS15.1.1正式版翻车?用了10天,大家的体验竟相差这么大
- 百度|百度智能云正在干一件大事,中国实体经济将这么走
- pua|司马南这么一闹,国企可能要公开招标了,联想会被洗牌?
- 我们来了|整蛊好友无底线?微信隐藏表情包,原来这么简单
- 华为|用十多年的体验说话:联想的电脑比惠普的结实耐用
- 腾讯|网传一份腾讯员工收入证明,其税后收入 251 万,大厂工资真这么高吗?