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中操作日期和时间之gmtime()方法的使用
May 22 Python
Python实现修改文件内容的方法分析
Mar 25 Python
对numpy数据写入文件的方法讲解
Jul 09 Python
Django框架使用富文本编辑器Uedit的方法分析
Jul 31 Python
Python实现将Excel转换成xml的方法示例
Aug 25 Python
python中的global关键字的使用方法
Aug 20 Python
python实现门限回归方式
Feb 29 Python
django 取消csrf限制的实例
Mar 13 Python
Python多线程的退出控制实现
Aug 10 Python
python实现二分查找算法
Sep 18 Python
只用50行Python代码爬取网络美女高清图片
Jun 02 Python
聊聊Python String型列表求最值的问题
Jan 18 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函数,php爱好者站推荐
2007/03/19 PHP
PHP面向对象学习笔记之一 基础概念
2012/10/06 PHP
浅析memcache启动以及telnet命令详解
2013/06/28 PHP
php修改上传图片尺寸的方法
2015/04/14 PHP
javascript函数库-集合框架
2007/04/27 Javascript
Javascript学习笔记7 原型链的原理
2010/01/11 Javascript
jQuery学习5 jQuery事件模型
2010/02/07 Javascript
跟着JQuery API学Jquery 之三 筛选
2010/04/09 Javascript
深入理解JavaScript系列(7) S.O.L.I.D五大原则之开闭原则OCP
2012/01/15 Javascript
JS小功能(button选择颜色)简单实例
2013/11/29 Javascript
javascript中利用柯里化函数实现bind方法
2016/04/29 Javascript
js实现的下拉框二级联动效果
2016/04/30 Javascript
Javascript的比较汇总
2016/07/25 Javascript
老生常谈JavaScript 正则表达式语法
2016/08/20 Javascript
Node.js配合node-http-proxy解决本地开发ajax跨域问题
2016/08/31 Javascript
利用JS对iframe父子(内外)页面进行操作的方法教程
2017/06/15 Javascript
高性能js数组去重(12种方法,史上最全)
2019/12/21 Javascript
js仿360开机效果
2019/12/26 Javascript
小程序实现密码输入框
2020/11/16 Javascript
python发送HTTP请求的方法小结
2015/07/08 Python
详解Golang 与python中的字符串反转
2017/07/21 Python
解决PyCharm中光标变粗的问题
2017/08/05 Python
Python使用matplotlib 画矩形的三种方式分析
2019/10/31 Python
python识别验证码图片实例详解
2020/02/17 Python
浅谈python print(xx, flush = True) 全网最清晰的解释
2020/02/21 Python
Python如何实现大型数组运算(使用NumPy)
2020/07/24 Python
Python就将所有的英文单词首字母变成大写
2021/02/12 Python
基于IE10/HTML5 开发
2013/04/22 HTML / CSS
英国演唱会订票网站:Ticket Selection
2018/03/27 全球购物
Pretty Little Thing美国:时尚女性服饰
2018/08/27 全球购物
斯图尔特·韦茨曼鞋加拿大官网:Stuart Weitzman加拿大
2019/10/13 全球购物
会计岗位职责
2013/11/08 职场文书
高三地理教学反思
2014/01/11 职场文书
教导主任竞聘演讲稿
2014/05/16 职场文书
隐形的翅膀观后感
2015/06/10 职场文书
吉利入股戴姆勒后smart“长大了”
2022/04/21 数码科技