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实现定制交互式命令行的方法
Jul 03 Python
使用C语言扩展Python程序的简单入门指引
Apr 14 Python
python自动截取需要区域,进行图像识别的方法
May 17 Python
在python3中pyqt5和mayavi不兼容问题的解决方法
Jan 08 Python
Python 安装第三方库 pip install 安装慢安装不上的解决办法
Jun 18 Python
解决Python内层for循环如何break出外层的循环的问题
Jun 24 Python
Python的numpy库下的几个小函数的用法(小结)
Jul 12 Python
如何更改 pandas dataframe 中两列的位置
Dec 27 Python
tensorflow mnist 数据加载实现并画图效果
Feb 05 Python
python BeautifulSoup库的安装与使用
Dec 17 Python
Python中生成ndarray实例讲解
Feb 22 Python
python FTP编程基础入门
Feb 27 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
不用iconv库的gb2312与utf-8的互换函数
2006/10/09 PHP
六酷社区论坛HOME页清新格调免费版 下载
2007/03/07 PHP
php完全过滤HTML,JS,CSS等标签
2009/01/16 PHP
CI(CodeIgniter)框架配置
2014/06/10 PHP
使用ThinkPHP+Uploadify实现图片上传功能
2014/06/26 PHP
JavaScript将页面表格导出为Excel的具体实现
2013/12/27 Javascript
JavaScript作用域示例详解
2016/07/07 Javascript
vue实现可增删查改的成绩单
2016/10/27 Javascript
JQuery中Ajax的操作完整例子
2017/03/07 Javascript
微信小程序 仿美团分类菜单 swiper分类菜单
2017/04/12 Javascript
微信小程序实现登录页云层漂浮的动画效果
2017/05/05 Javascript
微信JS SDK接入的几点注意事项(必看篇)
2017/06/23 Javascript
详解NODEJS基于FFMPEG视频推流测试
2017/11/17 NodeJs
详解各版本React路由的跳转的方法
2018/05/10 Javascript
vue translate peoject实现在线翻译功能【新手必看】
2018/06/07 Javascript
简单说说如何使用vue-router插件的方法
2019/04/08 Javascript
vuex 动态注册方法 registerModule的实现
2019/07/03 Javascript
vue实现表单录入小案例
2019/09/27 Javascript
vue祖孙组件之间的数据传递案例
2020/12/07 Vue.js
[01:28:44]DOTA2-DPC中国联赛定级赛 RNG vs iG BO3第一场 1月10日
2021/03/11 DOTA
python改变日志(logging)存放位置的示例
2014/03/27 Python
Python实现批量修改文件名实例
2015/07/08 Python
python爬虫headers设置后无效的解决方法
2017/10/21 Python
基于python批量处理dat文件及科学计算方法详解
2018/05/08 Python
华为校园招聘上机笔试题 扑克牌大小(python)
2020/04/22 Python
django如何通过类视图使用装饰器
2019/07/24 Python
Python使用百度api做人脸对比的方法
2019/08/28 Python
python如何将两个txt文件内容合并
2019/10/18 Python
TheFork葡萄牙:欧洲领先的在线餐厅预订平台
2019/05/27 全球购物
优良学风班申请材料
2014/02/13 职场文书
乡镇干部个人对照检查材料思想汇报
2014/10/04 职场文书
2014年医德医风工作总结
2014/11/13 职场文书
论文答辩开场白大全
2015/05/27 职场文书
详解MySQL的半同步
2021/04/22 MySQL
React 并发功能体验(前端的并发模式)
2021/07/01 Javascript
python多线程方法详解
2022/01/18 Python