在日常使用中,我们有时候会希望能固定函数的一些参数,以此来减少参数的个数,方便函数的调用。
例如有一个列表:
>>> num = list(range(1, 6))
>>> num
[1, 2, 3, 4, 5]
我们希望把它的元素都乘以3,如果用lambda表示式可以这么做:
>>> list(map(lambda x: x * 3, num))
[3, 6, 9, 12, 15]
如果不想用lambda表达式,可以使用python自带的mul函数。但是mul默认有两个参数,传递给map的函数只能有一个,该怎么办呢?
这里就可以使用functools里的partial函数,给mul函数绑定一个参数,变成只需要一个参数的新函数。
>>> from operator import mul
>>> from functools import partial
>>> triple = partial(mul, 3)
>>> list(map(triple, num))
[3, 6, 9, 12, 15]
除了定位参数,partial还可以绑定关键字参数:
>>> def show(a, b, c, d):
... print(a, b, c, d)
...
>>> binded = partial(show, 1, c=3)
>>> binded(2, d=4) # 绑定c后,d只能以关键字参数的形式传递了
1 2 3 4
除此之外,有的函数参数很多,又要反复调用,如果其中部分参数是相同的,就可以使用partial函数来绑定,避免重复劳动(否则需要修改时挨个修改也很容易出错)。
但是,类似的功能lambda也可以搞定,使用partial有什么好处呢?
我现在知道的有两点不同,一个是:
>>> from operator import add
>>> n = 5
>>> addn = lambda x: add(x, n)
>>> addn2 = partial(add, n)
>>> addn(1)
6
>>> addn2(1)
6
>>> n = 10
>>> addn(1)
11
>>> addn2(1)
6
partial函数中的变量传递的是值,而lambda表达式中的变量就是变量,会以闭包的形式绑定到函数上。
lambda表达式也可以避免这个问题,但确实是个容易出错的地方:
>>> n = 5
>>> addn = lambda x, n=n: add(x, n)
>>> addn(1)
6
>>> n = 10
>>> addn(1)
6
另外一个不同是:
>>> show1 = lambda a, b, c: show(a, b, c, d=1)
>>> show1(1, 2, 3)
1 2 3 1
>>> show2 = partial(show, d=1)
>>> show2(1, 2, 3)
1 2 3 1
>>> show2(1, 2, 3, d=4)
1 2 3 4
partial会记录下来参数,实际调用的还是原函数。
lambda表达式同样也可以避免这个问题,但就显得不够简洁好看了:
>>> show1 = lambda a, b, c, d=1: show(a, b, c, d)
>>> show1(1, 2, 3)
1 2 3 1
>>> show1(1, 2, 3, d=4)
1 2 3 4
参考资料:
[1] Python Cookbook 3rd Edition Documentation 第7章
[2] https://stackoverflow.com/questions/3252228/python-why-is-functools-partial-necessary
网友评论