python functools.partial 的理解

首先我们看看官方文档的定义:
Return a new partial object which when called will behave like func called with the positional arguments args and keyword arguments keywords.

  1. If more arguments are supplied to the call, they are appended to args.
  2. If additional keyword arguments are supplied, they extend and override keywords. Roughly equivalent to:
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):
    return x + y + z

a1 = partial(add, 10, 20)
# 60
print(a1(30))

# functools.partial(<function add at 0x7f90d97b9730>, 10, 20)
print(a1)

分部解释:

  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

解释说明:

  1. attach_wrap(sub)执行,发现func2为None,所以执行if语句: partial(attach_wrap, func1)的返回相当于:
  2. sub1 = attach_wrap(*(func1), *fargs, **fkwargs)
  3. 调用sub1(div),这时候func2为div函数,所以把func2设置为func1的属性
  4. 返回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))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值