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


Posted in Python onJune 22, 2021

泛型,如果你学过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单分派泛函数的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
下载给定网页上图片的方法
Feb 18 Python
wxPython中listbox用法实例详解
Jun 01 Python
django加载本地html的方法
May 27 Python
Python爬虫实现简单的爬取有道翻译功能示例
Jul 13 Python
python中copy()与deepcopy()的区别小结
Aug 03 Python
python实现决策树分类
Aug 30 Python
Python中将两个或多个list合成一个list的方法小结
May 12 Python
用python打印1~20的整数实例讲解
Jul 01 Python
Python在Matplotlib图中显示中文字体的操作方法
Jul 29 Python
如何使用PyCharm将代码上传到GitHub上(图文详解)
Apr 27 Python
python 图像插值 最近邻、双线性、双三次实例
Jul 05 Python
Python 利用argparse模块实现脚本命令行参数解析
Dec 28 Python
Python实现DBSCAN聚类算法并样例测试
python中sqllite插入numpy数组到数据库的实现方法
Jun 21 #Python
利用Python第三方库实现预测NBA比赛结果
Django实现drf搜索过滤和排序过滤
python生成可执行exe控制Microsip自动填写号码并拨打功能
详解Python自动化之文件自动化处理
Jun 21 #Python
Python Pandas pandas.read_sql_query函数实例用法分析
Jun 21 #Python
You might like
解决163/sohu/sina不能够收到PHP MAIL函数发出邮件的问题
2009/03/13 PHP
PHP+Mysql+jQuery实现发布微博程序 jQuery篇
2011/10/08 PHP
PHP、Nginx、Apache中禁止网页被iframe引用的方法
2020/10/01 PHP
从零开始学YII2框架(一)通过Composer安装Yii2框架
2014/08/20 PHP
php操作redis缓存方法分享
2015/06/03 PHP
JavaScript方法和技巧大全
2006/12/27 Javascript
greybox——不开新窗口看新的网页
2007/02/20 Javascript
javascript arguments 传递给函数的隐含参数
2009/08/21 Javascript
测试JavaScript字符串处理性能的代码
2009/12/07 Javascript
javascript 事件查询综合 推荐收藏
2010/03/10 Javascript
jquery checkbox,radio是否选中的判断代码
2010/03/20 Javascript
jQuery实现带有动画效果的回到顶部和底部代码
2015/11/04 Javascript
使用Vue.js创建一个时间跟踪的单页应用
2016/11/28 Javascript
thinkjs之页面跳转同步异步操作
2017/02/05 Javascript
js清除浏览器缓存的几种方法
2017/03/15 Javascript
Angular4如何自定义首屏的加载动画详解
2017/07/26 Javascript
使用angularjs.foreach时return的问题解决
2018/09/30 Javascript
nodejs读取本地中文json文件出现乱码解决方法
2018/10/10 NodeJs
深入理解JavaScript 中的执行上下文和执行栈
2018/10/23 Javascript
Vue的props父传子的示例代码
2020/05/20 Javascript
Python自动化运维和部署项目工具Fabric使用实例
2016/09/18 Python
详解TensorFlow查看ckpt中变量的几种方法
2018/06/19 Python
python实现列表中由数值查到索引的方法
2018/06/27 Python
python仿evething的文件搜索器实例代码
2019/05/13 Python
python flask框架实现传数据到js的方法分析
2019/06/11 Python
python 3.7.4 安装 opencv的教程
2019/10/10 Python
python分布式编程实现过程解析
2019/11/08 Python
python 解决cv2绘制中文乱码问题
2019/12/23 Python
Python如何把多个PDF文件合并代码实例
2020/02/13 Python
LA MER海蓝之谜美国官网:传奇面霜
2016/08/27 全球购物
香港中原电器网上商店:Chung Yuen
2019/06/26 全球购物
英国百年闻名的优质健康产品连锁店:Holland & Barrett
2019/12/19 全球购物
C#面试题
2016/05/06 面试题
软件部经理岗位职责范本
2014/02/25 职场文书
辞职信怎么写
2015/02/27 职场文书
浅析MongoDB之安全认证
2021/06/26 MongoDB