python:functools.partial

762 阅读3分钟

前言

经常会看到有些代码中使用 functools.partial 来包装一个函数,之前没有太了解它的用法,只是按照别人的代码来写,今天仔细看了一下它的用法,基本的用法还是很简单的。

functools.partial 的基本使用

functools.partial用于高阶函数,主要是根据一个函数构建另一个新的函数。
functools.partial返回的是一个partial对象,使用方法是partial(func, *args, **kw),
其中func是必须有的,而且至少需要一个arg或者kw参数。

<1>demo1,函数只有一个入参

假设我们下面这样一个功能函数, 
该函数的功能是:传入一个参数,然后+1,最后返回结果
def addone(x):
    return x+1
    
我们正常调用这个功能函数
result = addone(3)
print(result)
得到的结果是4,这个很好理解。


如果我们再根据addone()这个函数构建一个新的函数,这个新函数的名字是add
def addone(x):
    return x+1

add = functools.partial(addone,3)

# 调用这个新函数add
print(add())
这时也会输出4。
这个4是怎么来的?
首先我们通过 add = functools.partial(addone, 3) 定义一个新的变量 add , 它相当于 addone(3) 的结果,此时的变量add是一个新的函数,
当执行add()函数时,其实执行的是addone(3),结果也是addone(3) 的结果,
这个add()函数返回的4也就是addone(3)的结果,这个4就是这么来的。


<2>demo2,函数有2个入参

下面是一个复杂一点的例子:
上面的addone()函数只有一个入参,我们现在多加一个入参数,让函数返回2个参数的和。
def sum(x,y):
    return x+y
    
resutl = sum(5,6)
print(result)

sumy = functools.partial(sum,5)
print(sumy(6))
输出结果:
print(sum(5, 6)) 这个输出 11 没有什么好说的,
print(sumY(6)) 这个也输出11,这个是怎么来的?
当使用 sumy = functools.partial(sum, 5) 定义sumy变量时,其实是将 sum(x, y) 函数中的x值固定为 5 ,所以当调用sumy(6) 的时候,其实是返回的是sum(5, 6) 的值,也就是说,sumy函数不用再传入x参数,而是固定为5。

kwargs 类型的参数
当一个函数的参数为k,v的形式该怎么定义partial函数呢?

<3>demo3,函数有3个入参

def add(x,y,z):
    return x+y+z
    
p = functools.partial(add, 12) 
# 这里构建了一个partial对象p,其实就是一个新的函数。
# 12是一个固定的参数,就是x,
# 当调用p的时候,只传入y和z参数就行了,因为x已经固定了。

调用这个新函数p
print(p(1,2))
得到的结果是15

<4>demo4,函数的参数是kv的形式

def show(name="yyx",age=100):
    return (name,age)
    
showp = functools.partial(show,age=5)
print(showp('zhangsanfeng'))

可以在定义新函数的时候,将对应的参数定义好,如果上面的age=18, 则新生成的函数相当于 show(name="yyx", age=18)

注意,这里如果使用partial定义了函数的参数,那么再调用的时候,就不能再传相应的参数了,如上面的已经在showp函数中定义了age=18了,在调用showp()时,只能传name参数,即只能使用showp(“yangyanxing”), 不能再传入一个age参数, showp(“yangyanxing”, 28), 如果再加上age参数,则会报错。

functools.partial()有什么用?

从上面的几个demo来看,似乎使用functools.partial也没有什么用,只是固定了某个参数的值,使原来的调用少传一个参数罢了,但是我们可能有某种函数场景,它的参数是也一个函数,比如回调函数。