泛型,如果你学过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
)。
单分派:根据一个参数的类型,以不同方式执行相同的操作的行为。
多分派:可根据多个参数的类型选择专门的函数的行为。
泛函数:多个函数绑在一起组合成一个泛函数。
这边举个简单的例子,介绍一下使用方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
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 等,不同数据类型的拼接方式各不相同,所以我这里我写了一个通用的函数,可以根据对应的数据类型对选择对应的拼接方式拼接,而且不同数据类型我还应该提示无法拼接。以下是简单的实现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
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 的话,你可能会写出这样的代码。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
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单分派泛函数的资料请关注服务器之家其它相关文章!
原文链接:https://www.cnblogs.com/wongbingming/p/10726698.html