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访问sqlserver示例
Feb 10 Python
Python win32com 操作Exce的l简单方法(必看)
May 25 Python
Python使用django搭建web开发环境
Jun 09 Python
Python实现比较扑克牌大小程序代码示例
Dec 06 Python
Python读取MRI并显示为灰度图像实例代码
Jan 03 Python
Python和Java进行DES加密和解密的实例
Jan 09 Python
详解Python字典小结
Oct 20 Python
python利用requests库模拟post请求时json的使用教程
Dec 07 Python
python协程之动态添加任务的方法
Feb 19 Python
关于pytorch处理类别不平衡的问题
Dec 31 Python
Django QuerySet查询集原理及代码实例
Jun 13 Python
opencv 阈值分割的具体使用
Jul 08 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中使用正则表达式进行查找替换
2013/06/13 PHP
PHP中使用gettext解决国际化问题的例子(i18n)
2014/06/13 PHP
在WordPress中使用PHP脚本来判断访客来自什么国家
2015/12/10 PHP
PHP使用preg_split()分割特殊字符(元字符等)的方法分析
2017/02/04 PHP
php中请求url的五种方法总结
2017/07/13 PHP
laravel框架数据库配置及操作数据库示例
2019/10/10 PHP
Ruffy javascript 学习笔记
2009/11/30 Javascript
javascript 正则替换 replace(regExp, function)用法
2010/05/22 Javascript
解析Javascript中大括号“{}”的多义性
2013/12/02 Javascript
javascript为按钮注册回车事件(设置默认按钮)的方法
2015/05/09 Javascript
jquery简单实现带渐显效果的选项卡菜单代码
2015/09/01 Javascript
JS对象创建的几种方式整理
2017/02/28 Javascript
angularJS 发起$http.post和$http.get请求的实现方法
2017/05/18 Javascript
nodejs接入阿里大鱼短信验证码的方法
2017/07/10 NodeJs
利用VS Code开发你的第一个AngularJS 2应用程序
2017/12/15 Javascript
jQuery实现基本动画效果的方法详解
2018/09/06 jQuery
uni-app如何实现增量更新功能
2020/01/03 Javascript
[26:24]完美副总裁、DOTA2负责人蔡玮专访:电竞如人生
2014/09/11 DOTA
python实现红包裂变算法
2016/02/16 Python
分享一下如何编写高效且优雅的 Python 代码
2017/09/07 Python
Python爬虫之正则表达式基本用法实例分析
2018/08/08 Python
Python字典创建 遍历 添加等实用基础操作技巧
2018/09/13 Python
python将txt文件读入为np.array的方法
2018/10/30 Python
python 实现分组求和与分组累加求和代码
2020/05/18 Python
新手常见Python错误及异常解决处理方案
2020/06/18 Python
Python Unittest原理及基本使用方法
2020/11/06 Python
英国优质鞋类专家:Robinson’s Shoes
2017/12/08 全球购物
台湾东南旅游社网站:东南旅游
2019/02/11 全球购物
《中华少年》教学反思
2014/02/15 职场文书
十佳好少年事迹材料
2014/08/21 职场文书
2014年教师党员自我评议
2014/09/19 职场文书
支部书记四风问题自我剖析材料
2014/09/29 职场文书
情侣之间的道歉短信
2015/05/12 职场文书
OpenCV-Python实现人脸磨皮算法
2021/06/07 Python
CSS使用伪类控制边框长度的方法
2022/01/18 HTML / CSS
Ruby处理CSV数据方法详解
2022/04/18 Ruby