Python中partial函数的工作原理

partial的代码示例:

>>> sum = lambda x, y : x + y
>>> sum(1, 2)
3
>>> incr = lambda y : sum(1, y)
>>> incr(2)
3
>>> def sum2(x, y):
    return x + y
>>> incr2 = functools.partial(sum2, 1)
>>> incr2(4)
5

大体上来讲,partial的功能可以表示成下边的形式:

def partial(func, *part_args):
    def wrapper(*extra_args):
        args = list(part_args)
        args.extend(extra_args)
        return func(*args)
return wrapper

因此,当调用partial(sum2, 1)时,实际上创建了一个类似sum2的新函数,不同之处是少了一个参数。传入的参数默认被1代替,也就是partial(sum2, 1)(4) == sum2(1, 4)

这种特殊的方式有许多的应用场景。这里举一个例子,假如你想在某个地方传递一个函数,并且,期望这个函数的参数是2个:

class EventNotifier(object):
    def __init__(self):
        self._listeners = []
    def add_listener(self, callback):
        ''' callback 接收两个参数, event 和 params '''
        self._listeners.append(callback)
        # ...
    def notify(self, event, *params):
        for f in self._listeners:
            f(event, params)

但是在某种情形下,在add_listener的callback函数中你需要接收第三个参数–context对象:

def log_event(context, event, params):
    context.log_event("Something happened %s, %s", event, params)

这里有几种解决方案:

1.创建一个特定的对象处理:
class Listener(object):
   def __init__(self, context):
       self._context = context
   def __call__(self, event, params):
       self._context.log_event("Something happened %s, %s", event, params)
notifier.add_listener(Listener(context))
2.Lambda方案:
log_listener = lambda event, params: log_event(context, event, params)
notifier.add_listener(log_listener)
3.partials方案:
context = get_context()  # whatever
notifier.add_listener(partial(log_event, context))

在上面的三种方案中,partial方法是最简洁和最快的。

[1]https://stackoverflow.com/questions/15331726/how-does-the-functools-partial-work-in-python

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值