Python中的偏函数和数学意义上的偏函数不一样!
执行函数时,要带上所有必要的参数进行调用。但有时参数可以在函数被调用之前提前获知。这种情况下,一个函数有一个或多个参数预先就能用上,以便函数能用更少的参数进行调用。我们知道通过设定参数的默认值,可以降低函数调用的难度。而偏函数也可以做到这一点。举例如下:
int()函数可以把字符串转换为整数,当仅传入字符串时,int()函数默认按十进制转换:
>>> int('123456') 123456 >>> int('123456',base=8) 42798 >>> int('123456',base=16) 1193046
我们看到int函数其实还有一个默认参数base,默认是10,当我们传入base=8,=16时,会分别以8进制和16进制转换。那如果要转换大量2进制字符串,每次都手动输入base=2比较繁琐,我们可以定义一个int2()函数,把默认base=2传入:
>>> def int2(x,base=2): return int(x,base) >>> int2('111000') 56 >>> int2('111001') 57
偏函数 partial
functools.partial可以帮助我们直接创建偏函数,不需要去单独定义int2,通过partial的用法直接生成int2这个新函数:
>>> import functools >>> int2 = functools.partial(int,base=2) >>> int2('111000') 56 >>> int2('111001') 57
所以,partial的作用可以理解为把函数的一些默认参数设为固定值,返回一个新函数,注意仅仅只是修改了参数默认值,实际使用时还是可以给函数传参修改参数的,接着上面的int2函数:
>>> int2('111001',base=10) 111001
最后,创建偏函数时,实际上可以接收函数对象、*args和**kw这3个参数,当传入:
int2 = functools.partial(int, base=2)
实际上固定了int()函数的关键字参数base,对于int2(‘10010’)相当于:
kw = { 'base': 2 } int('10010', **kw)
当传入:
max2 = functools.partial(max, 10)
实际上会把10作为*args的一部分自动加到左边,看下面的例子:
>>> max2 = functools.partial(max,10) >>> max2(1,5,9) 10 >>> args=(10,1,5,9) >>> max(*args) 10
使用partial给max函数增加了一个默认参数10,相当于把10加到了*args最左边。
当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。偏函数的这些应用看似简单,用途却很大,可以很好的执行DRY原则,节省编程成本。