Ein passender Lambda-Ausdruck "nichts tun" in Python?

77

Manchmal möchte ich, dass Platzhalter Lambda-Ausdrücke "nichts tun" machen, ähnlich wie wenn ich sage:

def do_nothing(*args):
    pass

Die folgende Syntax ist jedoch unzulässig, da Lambda-Ausdrücke versuchen, alles nach dem Doppelpunkt zurückzugeben, und Sie nicht zurückkehren können pass.

do_nothing = lambda *args: pass

Ich habe mich gefragt, ob der folgende Ausdruck ein geeigneter Ersatz für das oben Gesagte ist.

do_nothing = lambda *args: None

Ist es in Ordnung, einen Lambda-Ausdruck zu erstellen , der als Platzhalter-Lambda-Ausdruck verwendet wird, da die do_nothingobige Funktion technisch zurückgegeben Nonewird None? Oder ist es schlechte Praxis?

user3002473
quelle
Es macht dasselbe wie die do_nothingFunktion, aber es ist nicht klar, warum Sie ein lambdadafür verwenden müssen.
BrenBarn
Ich wollte lambdanur zur Lesbarkeit von Code verwenden, da ich persönlich kein Fan von verschachtelten Funktionen bin und die Anwendung, in der ich den Ausdruck verwenden wollte, eine dritte verschachtelte Funktion wäre. Ich bin auch einfach nur an anderen Meinungen über die Verwendung dieses Coding-Trops interessiert.
user3002473
1
In idiomatischem Python akzeptieren die meisten Stellen, an denen Sie eine Nichtstun-Funktion benötigen würden None, obwohl diese nicht aufrufbar ist. Das heißt:filter(None, alist)
Kojiro
6
Da alle Do-Nothing-Funktionen dasselbe nichts tun, können Sie sie einfach do_nothingan einer Stelle definieren und dann übergeben, do_nothingwann immer Sie ein Do-Nothing übergeben möchten. Es ist nicht erforderlich, es jedes Mal, wenn Sie es verwenden möchten, mit einem neuen Lambda (oder einem voll funktionsfähigen Def) neu zu definieren.
BrenBarn
mock.Mock()kann Ihr Dummy aufrufbar sein und beliebige Parameter akzeptieren. Aber es gibt einen anderen Mock zurück und es kann zu seltsamen Fehlern führen. Das Ändern in mock.Mock(return_value=None)kann immer noch fehlerhaft sein, da Sie versuchen können, ein Attribut daraus zu erhalten, und es funktioniert und ein weiteres Mock zurückgibt.
Strg-C

Antworten:

94

Dies:

def do_nothing(*args):
    pass

ist äquivalent zu:

lambda *args: None

Mit einigen kleinen Unterschieden ist man ein lambdaund einer nicht. ( __name__Wird zum Beispiel do_nothingauf der Funktion und <lambda>auf dem Lambda sein.) Vergessen Sie nicht **kwargs, wenn es für Sie wichtig ist. Funktioniert in Python ohne explizite return <x>Rückgabe None. Das ist hier :

Ein Aufruf gibt immer einen Wert zurück, möglicherweise None, es sei denn, er löst eine Ausnahme aus.

Ich habe ähnliche Funktionen als Standardwerte verwendet, zum Beispiel:

def long_running_code(progress_function=lambda percent_complete: None):
    # Report progress via progress_function.
Thanatos
quelle
Okay, danke für den Rat! Ich werde wahrscheinlich BrenBarns Vorschlag folgen, eine globale do_nothingFunktion zu schaffen.
user3002473
38

Wenn Sie wirklich eine vollständige Funktion haben möchten, stellen Sie sicher, dass Sie *args und nehmen *kwargs.

noop = lambda *args, **kwargs: None

In all seiner herrlichen Handlung

>>> noop = lambda *args, **kwargs: None
>>> noop("yes", duck_size="horse", num_ducks=100)
>>>

Randnotiz

Tun Sie sich selbst einen Gefallen für die Zukunft und schließen Sie die **kwargsHandhabung ein. Wenn Sie jemals versuchen, es irgendwo tief in Ihrem Code zu verwenden, und Sie vergessen haben, dass es nicht dauert , kwargsist es die Ausnahme, nichts zu tun:

In [2]: do_nothing('asdf', duck="yes")
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-efbd722f297c> in <module>()
----> 1 do_nothing('asdf', duck="yes")

TypeError: <lambda>() got an unexpected keyword argument 'duck'
Kyle Kelley
quelle
15

Manchmal werden Lambda-Funktionen für die Datentransformation verwendet, und in diesem Fall bedeutet "nichts tun", die Eingabe zurückzugeben, d. H.

lambda x: x

Um keine zurückzugeben, können Sie schreiben

lambda x: None

Paul
quelle
Dies ist nicht dasselbe wie eine Nichtstun-Funktion, die None zurückgibt.
BrenBarn
4
Ich mag diesen Gedanken. Es ist eher wie das Multiplikative identityals do_nothing. Vielleicht gibt es einen Grund, einen von jedem zu haben.
Peter Wood
10

Dies ist der einfachste Lambda-Ausdruck:

do_nothing = lambda: None

Keine Argumente erforderlich und die minimal erforderliche Rückgabe.

Rafa0809
quelle
2

In Python 3 müssen Sie dafür nicht einmal Funktionen definieren. Wenn type(None)Sie aufrufen , erhalten Sie den NoneTypeKonstruktor zurück, mit dem Sie nichts tun können : type(None)(). Beachten Sie, dass der NoneTypeKonstruktor nur 0 Argumente akzeptiert.

In Python 2NoneType ist es jedoch unmöglich, Instanzen von zu erstellen , lambda: Nonewas am sinnvollsten wäre.

Arthur Khazbs
quelle