lambda * args,** kwargs:无

时间:2013-08-02 19:12:08

标签: python lambda default-arguments

考虑:

blank_fn = lambda *args, **kwargs: None

def callback(x, y, z=''):
    print x, y, z

def perform_task(callback=blank_fn):
    print 'doing stuff'
    callback('x', 'y', z='z' )

这样做的动机是我不需要输入逻辑来检查是否已经分配回调,因为它默认为blank_fn,它什么都不做。

这有效,但是有一些原因我不应该这样做吗?它是pythonic吗?有没有更好的方法呢?是否内置了:

lambda *args, **kwargs: None

2 个答案:

答案 0 :(得分:35)

根据PEP8,您应该"始终使用def语句而不是将lambda表达式直接绑定到名称的赋值语句。"所以,我要改变的一件事是:

def blank_fn(*args, **kwargs):
    pass

但是,我认为这样做的一种更加pythonic的方式是:

def perform_task(callback=None):
    print 'doing stuff'
    if callback is not None:
        callback('x', 'y', z='z')

不应该调用不执行任何操作的函数。真值测试比函数调用便宜。

def do_nothing(*args, **kwargs): pass
def do_something(arg, callback=do_nothing):
    a = 1 + 2
    callback('z', z='z')
def do_something_else(arg, callback=None):
    a = 1 + 2
    if callback is not None:
        callback('z', z='z')

%timeit do_something(3)
1000000 loops, best of 3: 644 ns per loop

%timeit do_something_else(3)
1000000 loops, best of 3: 292 ns per loop

答案 1 :(得分:0)

我认为先前的答案是优越的,因为它提供了更好的方式来完成OP想要做的事情。

但是,在某些情况下,您可能需要在测试时使用noop功能,或者猴子正在修补某些东西。

因此,根据要求回答OP问题,您可以使用Mock:

In [1]: from mock import Mock

In [2]: blank_fn = Mock(return_value=None)

In [3]: blank_fn()

In [4]: blank_fn("foo")

In [5]: blank_fn(bar="foo")

In [6]: blank_fn("foobar", bar="foo")

In [7]: