web-dev-qa-db-fra.com

lambda * args, ** kwargs: Aucun

considérer:

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' )

La motivation pour le faire de cette façon est que je n'ai pas besoin de mettre en logique pour vérifier si le rappel a été attribué car il est par défaut vide_fn qui ne fait rien.

Cela fonctionne, mais y a-t-il une raison pour laquelle je ne devrais pas le faire? Est-ce pythonique? Y a-t-il une meilleure façon de le faire? Existe-t-il une fonction intégrée pour:

lambda *args, **kwargs: None
27
Scruffy

Selon PEP8 , vous devez "Toujours utiliser une instruction def au lieu d'une instruction d'affectation qui lie directement une expression lambda à un nom." Donc, une chose que je changerais est:

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

Cependant, je pense qu'une façon plus Pythonique de le faire est:

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

Il ne devrait pas être nécessaire d'appeler une fonction qui ne fait rien. Les tests de valeur de vérité sont moins chers que les appels de fonction.

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

Je pense que la réponse précédente est supérieure, car elle offre une meilleure façon d'accomplir ce que le PO voulait faire.

Cependant, il peut y avoir des circonstances où vous voulez une fonction noop lors des tests, ou si vous corrigez quelque chose.

Donc, pour répondre à la question OP comme demandé, vous pouvez utiliser 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]: 
0
DRendar