2015-02-10 5 views
5

Kann jemand dieses Verhalten von Lambda-Funktionen erklären?Lambda und mehrere Anweisungen in Python

import sys 
X = lambda: sys.stdout.write('first');sys.stdout.write("second") 
X() 

Returns: -> secondfirst

Und ein weiteres Problem:

lambda: sys.stdout.write("...");sys.exit(0) 

Oder

lambda: sys.exit(0);sys.stdout.write("...") 

nicht korrekt ausführen Hat. Und noch eine Frage, warum in der ersten Primer-Ausführung fließt von rechts nach links?

Der Versuch, mit: Python3 + (3.4, 3.2) OS: Linux (Ubuntu), OSX

+0

Warum möchten Sie ein Lambda so machen? –

+0

Ich möchte nicht Lambda auf diese Weise verwenden, erste Primer wurde in Code von Nagios Plugin gefunden, und ich bin neugierig, warum es auf diese Weise funktioniert :) – user4549992

+0

'Lambda' sind * Ausdrücke * und ihren Körper muss ein Ausdruck sein. Sie können ** keine Anweisung in ein Lambda schreiben, geschweige denn mehrere Anweisungen. – Bakuriu

Antwort

3

Es gibt zwei Aussagen auf der Linie, zunächst in einem lambda, die nur called nach dem sys.stdout.write("second") wird bereits ausgeführt . X() nennt das Lambda.

Es geht also nicht von rechts nach links, wir haben nur ein Lambda, das nur in der nächsten Zeile aufgerufen wird. Es ist nicht anders, als eine Funktion zu definieren, in sys.stdout zu schreiben und dann diese Funktion aufzurufen.

das äquivalent mit einer normalen Funktion Doing:

sys.stdout.write("second") 
def x(): 
    sys.stdout.write('first') 

x()  

Für Ihr weiteres Beispiel müssen Sie das Lambda zuweisen und dann rufen:

x= lambda: sys.exit(0);sys.stdout.write("...") 
x() 

ein ; Verwendung und mit mehreren Aussagen auf einem Linie ist nicht pythonisch oder eine sehr gute Idee im Allgemeinen.

+0

2 Befehle in einer Zeile haben mich verwirrt. Ich dachte, sie wären alle in Lambdas Körper. – user4549992

+0

@ user4549992, deshalb '' '' ist wirklich nie eine gute Idee. Mehrere Anweisungen ist nicht Pythonic und wie Sie herausgefunden haben, kann verwirrend sein –

+0

Ja: (Vielen Dank für die Antwort. – user4549992

2

ersten Code übersetzt:

import sys 
X = lambda: sys.stdout.write('first') 
sys.stdout.write("second") 
X() 

Wie Sie sehen können, ist es jetzt klar second läuft vor first.

9

sys.stdout.write ("zweite") ist nicht Teil des Lambda.

'zweite' wird immer gedruckt, auch wenn Sie X nicht anrufen. Mit anderen Worten, ruft X nur 'zuerst'.

Ihr Code kann wie neu geschrieben werden;

import sys 
X = lambda: sys.stdout.write('first') 
sys.stdout.write("second") 
print X() 

Wenn zwei vom Lambda ausgeführte Anweisungen in ein Tupel gesetzt werden sollen;

lambda: (sys.stdout.write('first'),sys.stdout.write("second")) 
3

Die Syntax für lambda ist:

lambda <args>: <expression> 

wo <expression> ein einziger Ausdruck sein muss. Es kann keine Anweisung oder mehrere Anweisungen oder mehrere durch ; getrennte Ausdrücke sein.

Was im Code passiert ist, dass lambda höhere Priorität als ; hat, so dass wird so analysiert: X = lambda: sys.stdout.write('first') gefolgt von sys.stdout.write("second"). Das Hinzufügen von Klammern um sys.stdout.write('first') ; sys.stdout.write("second") würde nicht funktionieren und einen Syntaxfehler erzeugen.

Mein Trick mehrere Dinge in einem Lambda zu tun ist:

f = lambda: [None, sys.stdout.write('first'), sys.stdout.write("second")][0] 

und der andere:

f = lambda: [None, sys.stdout.write("..."), sys.exit(0)][0] 

jedoch diese Art von Niederlagen der Zweck einer Lambda-Funktion, die zu tun ist, etwas kurz und wirklich einfach.

Ich denke, das wäre immer noch in Ordnung in Ihrem konkreten Beispiel, aber sieht irgendwie wie ein Hack aus.