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中查找excel某一列的重复数据 剔除之后打印
Feb 10 Python
pyqt4教程之实现半透明的天气预报界面示例
Mar 02 Python
python里对list中的整数求平均并排序
Sep 12 Python
python简单实现计算过期时间的方法
Jun 09 Python
pandas按若干个列的组合条件筛选数据的方法
Apr 11 Python
Python openpyxl 遍历所有sheet 查找特定字符串的方法
Dec 10 Python
Python 调用PIL库失败的解决方法
Jan 08 Python
python numpy 按行归一化的实例
Jan 21 Python
python-itchat 获取微信群用户信息的实例
Feb 21 Python
python列表删除和多重循环退出原理详解
Mar 26 Python
python获取本周、上周、本月、上月及本季的时间代码实例
Sep 08 Python
Python OpenCV实现图形检测示例详解
Apr 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制作图型计数器的例子
2006/10/09 PHP
ThinkPHP中Widget扩展的两种写法及调用方法详解
2017/05/04 PHP
基于Laravel实现的用户动态模块开发
2017/09/21 PHP
checkbox 多选框 联动实现代码
2008/10/22 Javascript
JS定时刷新页面及跳转页面的方法
2013/07/04 Javascript
Javascript call和apply区别及使用方法
2013/11/14 Javascript
jquery使整个div区域可以点击的方法
2015/06/24 Javascript
js实现瀑布流的三种方式比较
2020/06/28 Javascript
Bootstrap弹出框modal上层的输入框不能获得焦点问题的解决方法
2016/12/13 Javascript
js自制图片放大镜功能
2017/01/24 Javascript
js+html制作简单日历的方法
2017/06/27 Javascript
vue中的$emit 与$on父子组件与兄弟组件的之间通信方式
2018/05/13 Javascript
Js数组扁平化实现方法代码总汇
2020/11/11 Javascript
对于Python中线程问题的简单讲解
2015/04/03 Python
基于树莓派的语音对话机器人
2019/06/17 Python
mac系统下Redis安装和使用步骤详解
2019/07/09 Python
Python图像处理PIL各模块详细介绍(推荐)
2019/07/17 Python
运用PyTorch动手搭建一个共享单车预测器
2019/08/06 Python
Python socket模块方法实现详解
2019/11/05 Python
python中selenium库的基本使用详解
2020/07/31 Python
matplotlib自定义鼠标光标坐标格式的实现
2021/01/08 Python
CSS3新属性transition-property transform box-shadow实例学习
2013/06/06 HTML / CSS
深入浅析HTML5中的article和section的区别
2018/05/15 HTML / CSS
Shopee新加坡:东南亚与台湾电商平台
2019/01/25 全球购物
三星新西兰官网:Samsung新西兰
2019/03/05 全球购物
大学生专科毕业生自我评价
2013/11/17 职场文书
人事专员的职责
2014/02/26 职场文书
房产协议书范本
2014/10/18 职场文书
2014年司机工作总结
2014/11/21 职场文书
辞职信如何写
2015/02/27 职场文书
违规违纪检讨书范文
2015/05/06 职场文书
幼儿园春季开学通知
2015/07/16 职场文书
九九重阳节致辞
2015/07/31 职场文书
基于python制作简易版学生信息管理系统
2021/04/20 Python
golang goroutine顺序输出方式
2021/04/29 Golang
vscode中使用npm安装babel的方法
2021/08/02 Javascript