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 21 Python
浅谈Python爬取网页的编码处理
Nov 04 Python
Python实现的购物车功能示例
Feb 11 Python
对numpy中数组元素的统一赋值实例
Apr 04 Python
对Python 2.7 pandas 中的read_excel详解
May 04 Python
python画图系列之个性化显示x轴区段文字的实例
Dec 13 Python
Python装饰器基础概念与用法详解
Dec 22 Python
python微信聊天机器人改进版(定时或触发抓取天气预报、励志语录等,向好友推送)
Apr 25 Python
python实现视频分帧效果
May 31 Python
浅谈Pytorch中的torch.gather函数的含义
Aug 18 Python
Django之使用内置函数和celery发邮件的方法示例
Sep 16 Python
Python使用paramiko连接远程服务器执行Shell命令的实现
Mar 04 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
WINDOWS服务器安装多套PHP的另类解决方案
2006/10/09 PHP
php产生随机数的两种方法实例代码 输出随机IP
2011/04/08 PHP
PHP获取链表中倒数第K个节点的方法
2018/01/18 PHP
PHP array_reverse() 函数原理及实例解析
2020/07/14 PHP
js每次Title显示不同的名言
2008/09/25 Javascript
Javascript+XMLHttpRequest+asp.net无刷新读取数据库数据
2009/08/09 Javascript
jquery 插件开发方法小结
2009/10/23 Javascript
将查询条件的input、select清空
2014/01/14 Javascript
js获取input长度并根据页面宽度设置其大小及居中对齐
2014/08/22 Javascript
JavaScript必知必会(六) delete in instanceof
2016/06/08 Javascript
Bootstrap基本样式学习笔记之表单(3)
2016/12/07 Javascript
node.js请求HTTPS报错:UNABLE_TO_VERIFY_LEAF_SIGNATURE\的解决方法
2016/12/18 Javascript
js实现canvas保存图片为png格式并下载到本地的方法
2017/08/31 Javascript
JS库之Particles.js中文开发手册及参数详解
2017/09/13 Javascript
vuex state及mapState的基础用法详解
2018/04/19 Javascript
vue 2.8.2版本配置刚进入时候的默认页面方法
2018/09/21 Javascript
JavaScript解析机制与闭包原理实例详解
2019/03/08 Javascript
浅谈vue 多个变量同时赋相同值互相影响
2020/08/05 Javascript
[01:09:16]DOTA2-DPC中国联赛 正赛 SAG vs Dynasty BO3 第一场 1月25日
2021/03/11 DOTA
Python版的文曲星猜数字游戏代码
2013/09/02 Python
python僵尸进程产生的原因
2017/07/21 Python
Django中的Signal代码详解
2018/02/05 Python
Python实现高斯函数的三维显示方法
2018/12/29 Python
解决使用export_graphviz可视化树报错的问题
2019/08/09 Python
python实现的读取网页并分词功能示例
2019/10/29 Python
python求前n个阶乘的和实例
2020/04/02 Python
HTML5 DeviceOrientation实现手机网站摇一摇功能代码实例
2015/04/24 HTML / CSS
社区庆八一活动方案
2014/02/02 职场文书
大队委竞选演讲稿
2014/04/28 职场文书
庆祝三八妇女节标语
2014/10/09 职场文书
小学生思想品德评语
2014/12/31 职场文书
2015年党风廉政承诺书
2015/01/22 职场文书
公司回复函格式
2015/07/14 职场文书
Vue实现下拉加载更多
2021/05/09 Vue.js
python编程简单几行代码实现视频转换Gif示例
2021/10/05 Python
使用CSS实现六边形的图片效果
2022/08/05 HTML / CSS