python偏函数假如一个函数定义了多个位置参数,那你每次调用时,都需要把这些个参数一个一个地传递进去。
比如下面这个函数,是用来计算 x的n次方 的。
- def power(x, n):
- s = 1
- while n > 0:
- n = n - 1
- s = s * x
- return s
复制代码
那我每次计算 x 的 n 次方,都要传递两个参数
- >>> power(2, 2)
- 4
- >>> power(3, 2)
- 9
复制代码
后来我发现,我很多时候都是计算平方值,很多会去计算三次方,四次方。
那有什么办法可以偷个懒吗?
答案是,有。可以使用 偏函数。
偏函数(Partial Function),可以将某个函数的常用参数进行固定,避免每次调用时都要指定。
使用偏函数,需要导入 functools.partial ,然后利用它创建一个新函数,新函数的 n 固定等2。
具体使用请看下面的示例
- >>> from functools import partial
- >>> power_2=partial(power, n=2)
- >>> power_2(2)
- 4
- >>> power_2(3)
- 9
复制代码
python泛型函数根据传入参数类型的不同而调用不同的函数逻辑体,这种实现我们称之为泛型。在 Python 中叫做 singledispatch。
它使用方法极其简单,只要被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')
- 【错误】:参数类型不同,无法拼接!!
复制代码
|