Python 中的单分派泛函数你真的了解吗

作者:返回主页Python编程时光 时间:2023-03-12 04:32:26 

泛型,如果你学过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')
【错误】:参数类型不同,无法拼接!!

以上是我个人的一些理解,如有误解误传,还请你后台留言帮忙指正!

来源:https://www.cnblogs.com/wongbingming/p/10726698.html

标签:Python,单分派泛函数,singledispatch
0
投稿

猜你喜欢

  • Python+selenium实现自动循环扔QQ邮箱漂流瓶

    2021-07-12 23:46:28
  • Python任务调度模块APScheduler使用

    2021-08-23 05:45:44
  • 用python编写第一个IDA插件的实例

    2022-01-09 13:05:14
  • Python中的 pass 占位语句

    2023-02-21 20:45:12
  • 使用jupyter notebook运行python和R的步骤

    2023-03-30 18:22:50
  • Python中类的定义、继承及使用对象实例详解

    2023-07-11 17:10:37
  • Python列表list的详细用法介绍

    2021-04-17 06:56:15
  • Go语言异常处理案例解析

    2024-02-04 07:26:02
  • Python程序控制语句用法实例分析

    2021-04-13 06:59:48
  • ASP连接Access数据库和SQL server数据库的方法

    2007-08-22 13:16:00
  • vuex中数据持久化插件vuex-persistedstate使用详解

    2024-04-26 17:41:54
  • numpy中np.c_和np.r_的用法解析

    2021-02-09 17:54:06
  • Python三十行代码实现简单人脸识别的示例代码

    2022-08-29 18:07:49
  • pandas 实现分组后取第N行

    2023-02-09 11:11:40
  • js阻止移动端页面滚动的两种方法

    2023-08-04 17:36:12
  • 如何实现表单提交时提示正在发送

    2008-12-23 13:30:00
  • python比较两个列表是否相等的方法

    2023-04-10 06:29:18
  • python学习之whl文件解释与安装详解

    2021-11-01 18:09:14
  • PHP5在Apache下的两种模式的安装

    2023-11-24 05:18:08
  • Python Pandas 对列/行进行选择,增加,删除操作

    2022-10-29 03:55:52
  • asp之家 网络编程 m.aspxhome.com