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 相关文章推荐
探索Python3.4中新引入的asyncio模块
Apr 08 Python
Python中json格式数据的编码与解码方法详解
Jul 01 Python
Python中表示字符串的三种方法
Sep 06 Python
Python实现DDos攻击实例详解
Feb 02 Python
Python实现的旋转数组功能算法示例
Feb 23 Python
Python面向对象进阶学习
May 21 Python
python自带tkinter库实现棋盘覆盖图形界面
Jul 17 Python
Python数学形态学实例分析
Sep 06 Python
python的mysql数据库建立表与插入数据操作示例
Sep 30 Python
python django中8000端口被占用的解决
Dec 17 Python
PyQt5事件处理之定时在控件上显示信息的代码
Mar 25 Python
解决Python3.8运行tornado项目报NotImplementedError错误
Sep 02 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
动易数据转成dedecms的php程序
2007/04/07 PHP
php 数组排序 array_multisort与uasort的区别
2011/03/24 PHP
php实现获取农历(阴历)、节日、节气的类与用法示例
2017/11/20 PHP
PHP+Apache实现二级域名之间共享cookie的方法
2019/07/24 PHP
JObj预览一个JS的框架
2008/03/13 Javascript
javascript firefox不显示本地预览图片问题的解决方法
2008/11/12 Javascript
分析Node.js connect ECONNREFUSED错误
2013/04/09 Javascript
jquery获取复选框被选中的值
2014/03/22 Javascript
JavaScript计划任务后台运行的方法
2015/12/18 Javascript
jQuery Easyui DataGrid点击某个单元格即进入编辑状态焦点移开后保存数据
2016/08/15 Javascript
浅谈时钟的生成(js手写简洁代码)
2016/08/20 Javascript
JS遍历ul下的li点击弹出li的索引的实现方法
2016/09/19 Javascript
javascript自执行函数
2017/02/10 Javascript
jQuery+vue.js实现的九宫格拼图游戏完整实例【附源码下载】
2017/09/12 jQuery
JS实现瀑布流布局
2017/10/21 Javascript
Node.js使用MySQL连接池的方法实例
2018/02/11 Javascript
vue 循环加载数据并获取第一条记录的方法
2018/09/26 Javascript
async/await让异步操作同步执行的方法详解
2019/11/01 Javascript
js实现随机抽奖
2020/03/19 Javascript
javascript设计模式 ? 代理模式原理与用法实例分析
2020/04/16 Javascript
uniapp 仿微信的右边下拉选择弹出框的实现代码
2020/07/12 Javascript
[14:57]DOTA2 HEROS教学视频教你分分钟做大人-幽鬼
2014/06/13 DOTA
[32:47]完美世界DOTA2联赛 GXR vs IO 第二场 11.07
2020/11/09 DOTA
python之从文件读取数据到list的实例讲解
2018/04/19 Python
Python 普通最小二乘法(OLS)进行多项式拟合的方法
2018/12/29 Python
Html5实现首页动态视频背景的示例代码
2019/09/25 HTML / CSS
德国高品质男装及配饰商城:Cultizm(Raw Denim原色牛仔裤)
2018/04/16 全球购物
匡威西班牙官网:Converse西班牙
2019/10/01 全球购物
关键字throw与throws的用法差异
2016/11/22 面试题
毕业生求职简历的自我评价
2013/10/23 职场文书
高中的职业生涯规划书
2013/12/28 职场文书
关于环保的建议书400字
2014/03/12 职场文书
邀请书格式范文
2015/02/02 职场文书
毕业典礼主持词
2015/06/29 职场文书
Java中生成微信小程序太阳码的实现方案
2022/06/01 Java/Android