partial function

转自廖老师的 偏函数

Python 的 functools 模块提供了很多有用的功能, 其中一个就是偏函数 (Partial function). 要注意, 这里的偏函数和数学意义上的偏函数不一样.

在介绍函数参数的时候, 我们讲到, 通过设定参数的默认值, 可以降低函数调用的难度. 而偏函数也可以做到这一点. 举例如下:

int() 函数可以把字符串转换为整数, 当仅传入字符串时, int() 函数默认按十进制转换:

int('12345')
12345

int() 函数还提供额外的 base 参数, 默认值为 10. 如果传入 base 参数, 就可以做 N 进制的转换:

int('12345', base=8)
5349

int('12345', 16)
74565

假设要转换大量的二进制字符串, 每次都传入 int(x, base=2) 非常麻烦, 于是, 我们想到, 可以定义一个 int2() 的函数, 默认把 base=2 传进去:

def int2(x, base=2):
    return int(x, base)

这样, 我们转换二进制就非常方便了:

int2('1000000')
64

int2('1010101')
85

functools.partial 就是帮助我们创建一个偏函数的, 不需要我们自己定义 int2(), 可以直接使用下面的代码创建一个新的函数 int2():

import functools
int2 = functools.partial(int, base=2)

int2('1000000')
64

int2('1010101')
85

所以, 简单总结 functools.partial 的作用就是, 把一个函数的某些参数给固定住 (也就是设置默认值), 返回一个新的函数, 调用这个新函数会更简单.

注意到上面的新的 int2() 函数, 仅仅是把 base 参数重新设定默认值为 2, 但也可以在函数调用时传入其他值:

int2('1000000', base=10)
1000000

最后, 创建偏函数时, 实际上可以接收函数对象*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(5, 6, 7) 相当于:

args = (10, 5, 6, 7)
max(*args)

结果为 10.

总之, 当函数的参数个数太多, 需要简化时, 使用 functools.partial 可以创建一个新的函数, 这个新函数可以固定住原函数的部分参数, 从而在调用时更简单.

Last updated