导读 | Python的functools模块提供了很多有用的功能,其中一个就是偏函数(Partial function)。要注意,这里的偏函数和数学意义上的偏函数不一样。Python 偏函数是通过 functools 模块被用户调用。 |
偏函数 partial 应用
函数在执行时,要带上所有必要的参数进行调用。但是,有时参数可以在函数被调用之前提前获知。这种情况下,一个函数有一个或多个参数预先就能用上,以便函数能用更少的参数进行调用。
偏函数是将所要承载的函数作为partial()函数的第一个参数,原函数的各个参数依次作为partial()函数后续的参数,除非使用关键字参数。
通过语言描述可能无法理解偏函数是怎么使用的,那么就举一个常见的例子来说明。在这个例子里,我们实现了一个取余函数,对于整数 100,取得对于不同数 m 的 100%m 的余数。
from functools import partial def mod( n, m ): return n % m mod_by_100 = partial( mod, 100 ) print mod( 100, 7 ) # 2 print mod_by_100( 7 ) # 2
由于之前看到的例子一般选择加法或乘法来讲解,无法体会偏函数参数的位置问题,容易给人造成 partial 的第二个参数也是原函数的第二个参数的假象,所以我在这里选择 mod 来讲解。
而对于有关键字参数的情况下,就可以不按照原函数的参数位置和个数了。下面再看一个例子,讲的是如何进行不同的进制转换。
from functools import partial bin2dec = partial( int, base=2 ) print bin2dec( '0b10001' ) # 17 print bin2dec( '10001' ) # 17 hex2dec = partial( int, base=16 ) print hex2dec( '0x67' ) # 103 print hex2dec( '67' ) # 103
偏函数的这些应用看似简单,用途却很大,可以很好的执行DRY原则,节省编程成本。
关于偏函数,可以对现有函数进行加强。
>>> import functools >>> int2 =functools.partial (int, base=2) # 把 int 的转换设为二进制了,这里 base 是 int 函数表示进制的参数。 >>>int2('1000000') 64 >>>int2('1010101') 85
在重设之后, 也可以在函数调用时传入其他值:
>>> int2('1000000', base=10) # 这里 base 变成了 10,覆盖了已设的默认值 2。 1000000
注意这里在创建新的偏函数后,依旧可以更改已经设置的默认值,但是必须清晰指出是更改了 base 的值。
否则如果直接传如一个数值会报错:
int2('100', 10) # 报错,10 前未加 base=,不能分辨这是传给 base 的
原因如下:
创建偏函数时,实际上可以接收函数对象、*args 和 **kw 这 3 个参数,当传入:
int2 =functools.partial(int, base=2) # int 是函数对象,base=2 是 **kw,没有传入 *args 参数
实际上固定了 int() 函数的关键字参数 base,也就是:
int2('10010')
相当于:
kw = { 'base': 2 } int('10010', **kw) # 如果不指明 base=2 而只是传入 2 的话,那么 2 被认为是 *args 的值
当传入:
max2 =functools.partial(max, 10) # 这里的 10 显然就是作为 *args 里的值传入的
实际上会把 10 作为 *args 的一部分自动加到参数列表里去,也就是:
max2(5,6, 7) # 原本有 *args 的列表,然后会把 10 再加进去
相当于:
args = (10, 5, 6, 7) max(*args)
结果为 10。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/123451.html