web-dev-qa-db-ja.com

ラムダ* args、** kwargs:なし

考慮してください:

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
27
Scruffy

PEP8 によると、「ラムダ式を名前に直接バインドする割り当てステートメントではなく、常にdefステートメントを使用する」必要があります。だから、私が変更することの一つは:

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

ただし、これを行うためのよりPython的な方法は次のとおりです。

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
36
Chris Barker

前の答えは、OPがやりたいことを達成するためのより良い方法を提供するので、優れていると思います。

ただし、テスト時にnoop関数が必要な場合や、何かにパッチを適用している場合は、間違いなくあります。

したがって、OPの質問に答えるには、モックを使用できます。

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]: 
0
DRendar