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 相关文章推荐
Python获取远程文件大小的函数代码分享
May 13 Python
使用SAE部署Python运行环境的教程
May 05 Python
使用Python和xlwt向Excel文件中写入中文的实例
Apr 21 Python
Python对列表的操作知识点详解
Aug 20 Python
python通过opencv实现图片裁剪原理解析
Jan 19 Python
Python ORM编程基础示例
Feb 02 Python
对Python中 \r, \n, \r\n的彻底理解
Mar 06 Python
解决jupyter notebook 前面书写后面内容消失的问题
Apr 13 Python
Python使用monkey.patch_all()解决协程阻塞问题
Apr 15 Python
Python如何实现FTP功能
May 28 Python
windows10在visual studio2019下配置使用openCV4.3.0
Jul 14 Python
python通过新建环境安装tfx的问题
May 20 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
用PHP实现验证码功能
2006/10/09 PHP
ThinkPHP使用心得分享-ThinkPHP + Ajax 实现2级联动下拉菜单
2014/05/15 PHP
php自定义函数br2nl实现将html中br换行符转换为文本输入中换行符的方法【与函数nl2br功能相反】
2017/02/17 PHP
JQuery组件基于Bootstrap的DropDownList(完整版)
2016/07/05 Javascript
JS自定义混合Mixin函数示例
2016/11/26 Javascript
JavaScript优化以及前段开发小技巧
2017/02/02 Javascript
详解angularjs的数组传参方式的简单实现
2017/07/28 Javascript
vue 插值 v-once,v-text, v-html详解
2018/01/19 Javascript
JavaScript设计模式之原型模式分析【ES5与ES6】
2018/07/26 Javascript
js代码规范之Eslint安装与配置详解
2018/09/08 Javascript
浅谈express.js框架中间件(middleware)
2019/04/07 Javascript
小程序实现分类页
2019/07/12 Javascript
vue中axios的二次封装实例讲解
2019/10/14 Javascript
[46:20]DOTA2-DPC中国联赛 正赛 PSG.LGD vs LBZS BO3 第二场 1月22日
2021/03/11 DOTA
Python3使用SMTP发送带附件邮件
2020/06/16 Python
pandas 读取各种格式文件的方法
2018/06/22 Python
对python 匹配字符串开头和结尾的方法详解
2018/10/27 Python
python 实现GUI(图形用户界面)编程详解
2019/07/17 Python
Pycharm编辑器功能之代码折叠效果的实现代码
2020/10/15 Python
史上最详细的Python打包成exe文件教程
2021/01/17 Python
html5 Canvas画图教程(3)—canvas出现1像素线条模糊不清的原因
2013/01/09 HTML / CSS
Bonami斯洛伐克:购买家具和家居饰品
2019/07/02 全球购物
Ajax请求总共有多少种Callback
2016/07/17 面试题
个人评价范文分享
2014/01/11 职场文书
干部竞争上岗演讲稿
2014/09/11 职场文书
铅球加油稿100字
2014/09/26 职场文书
2014年纪检监察工作总结
2014/11/11 职场文书
白鹤梁导游词
2015/02/06 职场文书
2015政治思想表现评语
2015/03/25 职场文书
土建技术员岗位职责
2015/04/11 职场文书
答辩状格式范本
2015/05/22 职场文书
如何写新闻稿
2015/07/18 职场文书
教导处教学工作总结
2015/08/12 职场文书
2016年教师党员承诺书范文
2016/03/24 职场文书
2020年个人安全保证书参考模板
2020/01/08 职场文书
Python进程池与进程锁之语法学习
2022/04/11 Python