• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Python 中的单分派泛函数你真的了解吗

python 搞代码 4年前 (2022-01-07) 31次浏览 已收录 0个评论

singledispatch是标准库functools模块的函数 可以把整体方案拆成多个模块,甚至可以为你无法修改的类提供专门的函数,使用@singledispatch装饰的函数会变成泛函数,本文带领大家再次学习Python 中的单分派泛函数,一起学习下吧

泛型,如果你学过Java ,应该对它不陌生吧。但你可能不知道在 Python 中(3.4+ ),也可以实现简单的泛型函数。

在Python中只能实现基于单个(第一个)参数的数据类型来选择具体的实现方式,官方名称 是 single-dispatch。你或许听不懂,说简单点,就是可以实现第一个参数的数据类型不同,其调用的函数也就不同。

singledispatch 是 PEP443 中引入的,如果你对此有兴趣,PEP443 应该是最好的学习文档:

https://www.python.org/dev/peps/pep-0443/

A generic function is composed of multiple functions implementing the same operation for different types. Which implementation should be used during a call is determined by the dispatch algorithm. When the implementation is chosen based on the type of a single argument, this is known as single dispatch.

它使用方法极其简单,只要被singledispatch 装饰的函数,就是一个单分派的(single-dispatch )的泛函数(generic functions)。

单分派:根据一个参数的类型,以不同方式执行相同的操作的行为。
多分派:可根据多个参数的类型选择专门的函数的行为。

泛函数:多个函数绑在一起组合成一个泛函数。

这边举个简单的例子,介绍一下使用方法

 from functools import singledispatch @singledispatch def 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)  # int age('twenty three')  # str age(['23'])  # list

执行结果

我已经23岁了。
I am twenty three years old.
请传入合法类型的参数!

说起泛型,其实在 Python 本身的一些内建函数中并不少见,比如 len()iter()copy.copy()pprint()

你可能会问,它有什么用呢?实际上真没什么用,你不用它或者不认识它也完全不影响你编码。

我这里举个例子,你可以感受一下。

大家都知道,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 @singledispatch def add(obj, new_obj): raise TypeError @add.register(str) @check_type def _(obj, new_obj): obj += new_obj return obj @add.register(list) @check_type def _(obj, new_obj): obj.extend(new_obj) return obj @add.register(dict) @check_type def _(obj, new_obj): obj.update(new_obj) return obj @add.register(tuple) @check_type def _(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_type def add(obj, new_obj): if isinstance(obj, str) : obj += new_obj return obj if isinstance(obj, list) : obj.extend(new_obj) return obj if isinstance(obj, dict) : obj.update(new_obj) return obj if 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’)
【错误】:参数类型不同,无法拼接!!

以上是我个人的一些理解,如有误解误传,还请你后台留言帮忙指正!

以上就是Python 中的单分派泛函数你真的了解吗的详细内容,更多关于Python单分派泛函数的资料请关注gaodaima搞代码网来源gao*daima.com搞@代#码网其它相关文章!

以上就是Python 中的单分派泛函数你真的了解吗的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Python 中的单分派泛函数你真的了解吗

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址