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解析模块(ConfigParser)使用方法
Dec 10 Python
Python文本特征抽取与向量化算法学习
Dec 22 Python
浅谈Python批处理文件夹中的txt文件
Mar 11 Python
Python 循环终止语句的三种方法小结
Jun 24 Python
python中update的基本使用方法详解
Jul 17 Python
Python Pandas 如何shuffle(打乱)数据
Jul 30 Python
使用Python实现图像标记点的坐标输出功能
Aug 14 Python
python爬虫-模拟微博登录功能
Sep 12 Python
python框架flask表单实现详解
Nov 04 Python
python中使用paramiko模块并实现远程连接服务器执行上传下载功能
Feb 29 Python
基于Tensorflow的MNIST手写数字识别分类
Jun 17 Python
Python入门之使用pandas分析excel数据
May 12 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
mysql_fetch_assoc和mysql_fetch_row的功能加起来就是mysql_fetch_array
2007/01/15 PHP
php下利用curl判断远程文件是否存在的实现代码
2011/10/08 PHP
thinkPHP分组后模板无法加载问题解决方法
2016/07/12 PHP
PHP实现的Redis多库选择功能单例类
2017/07/27 PHP
PHP实现简单用户登录界面
2019/10/23 PHP
Firefox div高度自适应
2009/04/28 Javascript
禁止JQuery中的load方法装载IE缓存中文件的方法
2009/09/11 Javascript
JS localStorage实现本地缓存的方法
2013/06/22 Javascript
导航跟随滚动条置顶移动示例代码
2013/09/11 Javascript
原生js与jQuery实现简单的tab切换特效对比
2015/07/30 Javascript
node.js下LDAP查询实例分享
2015/09/30 Javascript
JS组件Bootstrap Table布局详解
2016/05/27 Javascript
手机移动端实现 jquery和HTML5 Canvas的幸运大奖盘特效
2016/12/06 Javascript
微信小程序实现动态设置页面标题的方法【附源码下载】
2017/11/29 Javascript
vue中各选项及钩子函数执行顺序详解
2018/08/25 Javascript
Vue和React组件之间的传值方式详解
2019/01/31 Javascript
js 将线性数据转为树形的示例代码
2019/05/28 Javascript
js面向对象封装级联下拉菜单列表的实现步骤
2021/02/08 Javascript
Python2.x中str与unicode相关问题的解决方法
2015/03/30 Python
python从入门到精通(DAY 3)
2015/12/20 Python
Python绘制正余弦函数图像的方法
2018/08/28 Python
Python 一行代码能实现丧心病狂的功能
2020/01/18 Python
vscode写python时的代码错误提醒和自动格式化的方法
2020/05/07 Python
面向新手解析python Beautiful Soup基本用法
2020/07/11 Python
python获取时间戳的实现示例(10位和13位)
2020/09/23 Python
CSS3中伪元素::before和::after的用法示例
2017/09/18 HTML / CSS
Canvas globalCompositeOperation
2018/12/18 HTML / CSS
艺术专业大学生自我评价
2013/09/22 职场文书
校优秀毕业生主要事迹
2014/05/26 职场文书
新课培训心得体会
2014/09/03 职场文书
党旗在我心中演讲稿
2014/09/15 职场文书
中国文明网向国旗敬礼活动精彩寄语2014
2014/09/27 职场文书
销售员工作检讨书(推荐篇)
2014/10/18 职场文书
初三毕业评语
2014/12/26 职场文书
辣妈辣妹观后感
2015/06/10 职场文书
python ConfigParser库的使用及遇到的坑
2022/02/12 Python