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 相关文章推荐
c++生成dll使用python调用dll的方法
Jan 20 Python
跟老齐学Python之折腾一下目录
Oct 24 Python
AI人工智能 Python实现人机对话
Nov 13 Python
python 使用poster模块进行http方式的文件传输到服务器的方法
Jan 15 Python
Python3实现的判断环形链表算法示例
Mar 07 Python
对python中的控制条件、循环和跳出详解
Jun 24 Python
Python中栈、队列与优先级队列的实现方法
Jun 30 Python
SELENIUM自动化模拟键盘快捷键操作实现解析
Oct 28 Python
浅析python内置模块collections
Nov 15 Python
详解django中Template语言
Feb 22 Python
python中pathlib模块的基本用法与总结
Aug 17 Python
opencv深入浅出了解机器学习和深度学习
Mar 17 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
Windows7下PHP开发环境安装配置图文方法
2010/05/20 PHP
Zend Framework连接Mysql数据库实例分析
2016/03/19 PHP
一些常用且实用的原生JavaScript函数
2010/09/08 Javascript
jquery $(this).attr $(this).val方法使用介绍
2013/10/08 Javascript
javascript特殊用法示例介绍
2013/11/29 Javascript
解析JavaScript中instanceof对于不同的构造器或许都返回true
2013/12/03 Javascript
jquery中页面Ajax方法$.load的功能使用介绍
2014/10/20 Javascript
JavaScript监听文本框回车事件并过滤文本框空格的方法
2015/04/16 Javascript
JavaScript Length 属性的总结
2015/11/02 Javascript
基于JavaScript短信验证码如何实现
2016/01/24 Javascript
js简单实现调整网页字体大小的方法
2016/07/23 Javascript
Swiper自定义分页器使用详解
2017/12/28 Javascript
Vue 中的compile操作方法
2018/02/26 Javascript
vue权限路由实现的方法示例总结
2018/07/29 Javascript
vue 本地环境跨域请求proxyTable的方法
2018/09/19 Javascript
JavaScript使用闭包模仿块级作用域操作示例
2019/01/21 Javascript
深入理解nodejs搭建静态服务器(实现命令行)
2019/02/05 NodeJs
Vue-Cli项目优化操作的实现
2019/10/27 Javascript
[46:48]DOTA2上海特级锦标赛A组小组赛#2 Secret VS CDEC第三局
2016/02/25 DOTA
[05:59]带你看看DPC的台前幕后
2021/03/11 DOTA
python抓取网页图片并放到指定文件夹
2014/04/24 Python
python xml解析实例详解
2016/11/14 Python
unittest+coverage单元测试代码覆盖操作实例详解
2018/04/04 Python
关于pymysql模块的使用以及代码详解
2019/09/01 Python
使用OpenCV circle函数图像上画圆的示例代码
2019/12/27 Python
解决python调用自己文件函数/执行函数找不到包问题
2020/06/01 Python
Java多线程实现四种方式原理详解
2020/06/02 Python
浅谈cv2.imread()和keras.preprocessing中的image.load_img()区别
2020/06/12 Python
HTML5本地存储之Web Storage应用介绍
2013/01/06 HTML / CSS
澳大利亚牛仔裤商店:Just Jeans
2016/10/13 全球购物
德国自然时尚和有机产品购物网站:Waschbär
2019/05/29 全球购物
彩妆大赛策划方案
2014/05/13 职场文书
村主任群众路线教育实践活动个人对照检查材料思想汇报
2014/10/01 职场文书
学生旷课检讨书500字
2014/10/28 职场文书
大学自主招生自荐信(2016精选篇)
2016/01/28 职场文书