python functools.partial 偏函数

2018-11-12  本文已影响0人  lxy_悦

Python的functools模块提供了很多有用的功能,其中一个就是偏函数(Partial function)。
partial 这个东西是针对函数起作用的,并且是部分的。装饰器是对函数进行包装,算是对函数的整体进行处理(其实是对输入和输出)。部分的话其实只有对参数进行部分处理了。怎么部分处理的呢?

def partial(func, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = keywords.copy()
        newkeywords.update(fkeywords)
        return func(*args, *fargs, **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc

我们一步一步的读:

  1. 闭包定义了一个新的函数newfunc,有2个参数签名fargs和fkeywords。这个newfunc的函数体很简单,就是把partial函数的参数和newfunc函数的参数合并起来给partial函数的第一个参数func函数执行,返回执行后的结果。
  2. 把partial函数的参数属性赋值给newfunc
  3. 返回newfunc

示例:

from functools import partial

def add(x, y, z):
    print x, y, z
    return x + y + z

add1 = partial(add, 10)
print(add1(20, 30))

输出:
10 20 30
60

分部解释:

  1. partial函数的参数:func=add,args=(10, 20)
  2. 通过获得partial的返回值:a1 = partial(add, 10, 20)。把返回的newfunc赋值给了a1,则执行a1(30) 与 add(*(10, 20), 30)等价。

复杂的示例说明:
如果我的partial函数第二值传的是个函数,会发生什么事情呢?看如下示例。

def sub(x, y):
    return x - y

def div(x, y):
    return x/y

def attach_wrap(func1, func2=None):
    if func2 is None:
        return partial(attach_wrap, func1)
    setattr(func1, func2.__name__, func2)
    return func1

sub1 = attach_wrap(sub)
print(sub1)

sub2 = sub1(div)
print(sub2)

print(sub2(20, 10)) //10
print(sub2.div(20, 10)) //2.0

解释说明:

attach_wrap(sub)执行,发现func2为None,所以执行if语句: partial(attach_wrap, func1)的返回相当于:
sub1 = attach_wrap(*(func1), *fargs, **fkwargs)
调用sub1(div),这时候func2为div函数,所以把func2设置为func1的属性
返回func1,结果就是func1绑定了func2函数
上面的这种写法经常可以用来在一个函数上绑定另一个函数:

def sub(x, y):
    return x - y

def attach_wrap(func1, func2=None):
    if func2 is None:
        return partial(attach_wrap, func1)
    setattr(func1, func2.__name__, func2)
    return func1

@attach_wrap(sub)
def div(x, y):
    return x/y

print(sub(10, 5))
print(sub.div(10, 5))
文章来源:

python functools.partial 的理解

上一篇下一篇

猜你喜欢

热点阅读