Sehr selten werde ich auf Code in Python stoßen, der eine anonyme Funktion verwendet, die eine anonyme Funktion zurückgibt ...?
Leider kann ich kein Beispiel finden, aber normalerweise hat es folgende Form:
%Vor%Warum sollte jemand das tun? Vielleicht können Sie ein Beispiel geben, das einen Sinn ergibt (ich bin nicht sicher, ob der, den ich gemacht habe, einen Sinn ergibt).
Bearbeiten: Hier ist ein Beispiel:
%Vor%Sie können ein solches Konstrukt verwenden, um currying durchzuführen:
%Vor%Sie könnten es verwenden wie:
%Vor%Siehe das () am Ende? Das innere Lambda wird nicht zurückgegeben, es wird aufgerufen.
Die Funktion führt das Äquivalent von
aus %Vor% Aber nehmen wir an, dass wir das in einem Lambda machen wollen. Wir können keine Zuweisungen in einem Lambda verwenden. Wir können jedoch __setitem__
für denselben Effekt aufrufen.
Aber für ein Lambda können wir nur einen Ausdruck haben. Aber da es sich um Funktionsaufrufe handelt, können wir sie in ein Tupel einfügen
%Vor% Aber all diese __setitem__
bringen mich runter, also lasst uns sie ausklammern:
Dagnamit, ich komme nicht damit durch, einen weiteren Auftrag hinzuzufügen! Ich weiß, lass uns Standardparameter missbrauchen.
%Vor%Ok, lass uns zu lambdas wechseln:
%Vor%Was uns zum ursprünglichen Ausdruck zurückbringt (Plus / Minus-Tippfehler)
All dies führt zurück auf die Frage: Warum?
Die Funktion hätte als
implementiert werden sollen %Vor%Der ursprüngliche Autor hat sich viel Mühe gegeben, ein Lambda anstatt einer Funktion zu verwenden. Es könnte sein, dass er aus irgendeinem Grund die verschachtelte Funktion nicht mag. Ich weiß es nicht. Alles, was ich sagen werde, ist sein schlechter Code. (Es sei denn, es gibt eine mysteriöse Begründung dafür.)
Dies kann für temporäre Platzhalter nützlich sein. Angenommen, Sie haben eine Dekorfabrik:
%Vor%Sie können es vorübergehend durch
ersetzen %Vor%Es kann auch nützlich sein, wenn es indirekt ein Lambda zurückgibt:
%Vor%Es ist auch nützlich, um aufrufbare Fabriken in der Python-Konsole zu erstellen.
Und nur weil etwas möglich ist, heißt das nicht, dass Sie es benutzen müssen.
Dies kann verwendet werden, um einen gewöhnlichen repetitiven Code zu ziehen (es gibt natürlich andere Möglichkeiten, dies in Python zu erreichen).
Vielleicht schreiben Sie einen Logger, und Sie müssen die Ebene der Protokollzeichenfolge voranstellen. Sie könnten etwas schreiben wie:
%Vor%Dieses Programm druckt
aus %Vor%Es ist am häufigsten - zumindest im Code, über den ich selbst schreibe -, eine Variable mit dem Wert "einzufrieren", den sie an dem Punkt hat, an dem die Lambda-Funktion erzeugt wird. Andernfalls referenziert die Variable nonlocals eine Variable in dem Bereich, in dem sie existieren, was manchmal zu nicht gewünschten Ergebnissen führen kann.
Zum Beispiel, wenn ich eine Liste von zehn Funktionen erstellen möchte, von denen jede ein Multiplikator für einen Skalar von 0 bis 9 ist. Man könnte versucht sein, es so zu schreiben:
%Vor%Wenn Sie eine der anderen factoried-Funktionen verwenden möchten, erhalten Sie dasselbe Ergebnis:
%Vor%Das liegt daran, dass die Variable "i" innerhalb des Lambda nicht aufgelöst wird, wenn das Lambda erzeugt wird. Stattdessen behält Python einen Verweis auf das "i" in der "for" -Anweisung - auf dem Bereich, in dem es erstellt wurde (diese Referenz wird in der lambda-Funktion closure beibehalten). Wenn das Lambda ausgeführt wird, wird die Variable ausgewertet, und ihr Wert ist der letzte in diesem Bereich.
Wenn man zwei verschachtelte Lambdas verwendet:
%Vor%Die Variable "i" wird während der Ausführung der "for" -Schleife ausgewertet. Der It¶-Wert wird an "k" übergeben - und "k" wird als nicht lokale Variable in der Multiplikatorfunktion verwendet, die wir ausschließen. Für jeden Wert von i gibt es eine andere Instanz der einschließenden Lambda-Funktion und einen anderen Wert für die Variable "k".
So ist es möglich, die ursprüngliche Absicht zu erreichen:
%Vor%Es kann verwendet werden, um eine Fortsetzung / Trampolining Stil der Programmierung zu erreichen,
Siehe Fortsetzungsstil