Kann jemand die konkreten Gründe erklären, warum BDFL Python Lambdas als Einzellinie verwendet?
Das ist gut:
lambda x: x**x
Dies führt zu einem Fehler:
lambda x:
x**x
Ich verstehe, dass das Herstellen von Lambda-Mehrfachzeilen die normalen Einrückungsregeln irgendwie "stören" und das Hinzufügen weiterer Ausnahmen erfordern würde, aber ist das nicht die Vorteile wert?
Schauen Sie sich zum Beispiel JavaScript an. Wie kann man ohne diese anonymen Funktionen leben? Sie sind unverzichtbar. Wollen Pythonisten nicht loswerden, dass sie jede mehrzeilige Funktion benennen müssen, nur um sie als Argument zu übergeben?
def
? Es hat jetzt genau die gleiche visuelle Struktur.Antworten:
Guido van van Rossum selbst antwortete:
http://www.artima.com/weblogs/viewpost.jsp?thread=147358
Grundsätzlich sagt er, dass eine Lösung zwar möglich ist, aber nicht mit Python übereinstimmt.
quelle
Es ist vollkommen in Ordnung, ein mehrzeiliges Lambda in Python zu machen: siehe
Die wirkliche Lambda-Beschränkung ist die Tatsache, dass Lambda ein einzelner Ausdruck sein muss . es darf kein Schlüsselwort enthalten (wie python2
print
oderreturn
).GvR wählt dies aus, um die Größe des Lambdas zu begrenzen, da diese normalerweise als Parameter verwendet werden. Wenn Sie eine echte Funktion wünschen, verwenden Sie
def
quelle
def
. Denken Sie darüber nach: Sie brauchen wirklich eine aufrufbare als Parameter Ihrer Funktion? Und die Benutzer dieser Funktion dürfen Ihr Standard-Callable nicht weitergeben? Wie können sie es bestehen, wenn Sie es ihnen nicht geben?Ich weiß, das ist super alt, aber hier als Referenz setzen.
Eine Alternative zur Verwendung von Lambda könnte darin bestehen, a
def
auf nicht herkömmliche Weise zu verwenden. Das Ziel ist es, einedef
an eine Funktion zu übergeben, was nur unter einem Umstand möglich ist - einem Dekorateur. Beachten Sie, dass mit dieser Implementierungdef result
keine Funktion erstellt wird, sondern das Ergebnis von erstellt wirdreduce()
, das letztendlich a istdict
.Shameless Stecker : Ich mache eine Menge von diesem hier .
Beachten Sie, dass Lambdas mit mehreren Anweisungen ausgeführt werden können , jedoch nur mit wirklich, wirklich hässlichem Code. Interessant ist jedoch, wie das Scoping bei dieser Implementierung funktioniert (beachten Sie die Mehrfachverwendung der
name
Variablen und das Shadowing dermessage
Variablen).quelle
Das Zusammenhacken eines Lambda mit mehreren Anweisungen ist nicht ganz so schlimm, wie es Pyrospade vermuten lässt: Sicher könnten wir eine Reihe monadischer Funktionen mit bind komponieren, wie in Haskell, aber da wir uns in der unreinen Welt von Python befinden, könnten wir es auch Verwenden Sie Nebenwirkungen, um das Gleiche zu erreichen.
In meinem Blog beschreibe ich einige Möglichkeiten, dies zu tun .
Zum Beispiel garantiert Python, dass die Elemente eines Tupels in der richtigen Reihenfolge ausgewertet werden, sodass wir sie
,
wie einen Imperativ verwenden können;
. Wir können viele Aussagenprint
durch Ausdrücke wie ersetzensys.stdout.write
.Daher sind die folgenden äquivalent:
Beachten Sie, dass ich
None
am Ende ein hinzugefügt und es mit extrahiert habe[-1]
. Dadurch wird der Rückgabewert explizit festgelegt. Wir müssen dies nicht tun, aber ohne es würden wir einen flippigen(None, None, None)
Rückgabewert erhalten, der uns vielleicht interessiert oder nicht.So können wir IO-Aktionen abfolgen. Was ist mit lokalen Variablen?
Pythons
=
bildet eine Aussage, also müssen wir einen äquivalenten Ausdruck finden. Eine Möglichkeit besteht darin, den Inhalt der als Argument übergebenen Datenstruktur zu mutieren. Zum Beispiel:Es gibt einige Tricks, die verwendet werden
stateful_lambda
:*_
Argument erlaubt unserem Lambda eine beliebige Anzahl von Argumenten. Da dies keine Argumente zulässt , stellen wir die Aufrufkonvention von wieder herstateful_def
._
ist nur eine Konvention, die besagt, dass ich diese Variable nicht verwenden werde.lambda state: lambda *_: ...
(lambda state: ...)({})
state
einem Wert eine Variable zuweisen ,{}
ohne eine Zuweisungsanweisung zu verwenden (z. B.state = {}
).state
als Variablennamen und gebundene Wertestate.setdefault(a, b)
anstelle vona = b
undstate.get(a)
anstelle vona
[-1]
, um den letzten Wert zu extrahieren, der sich wie einereturn
Anweisung verhältDas ist natürlich ziemlich umständlich, aber wir können eine schönere API mit Hilfsfunktionen erstellen:
quelle
Ich könnte zwar einen Beitrag leisten, benutze aber einen Zeilenumbruch:
Vergessen Sie nicht, wie schön es ist, dass Python Oneliners schreiben kann, wie im Beispiel:
Und das Lambda ist sehr mächtig, aber es ist nicht für die Ersetzung einer ganzen Funktion gedacht, ich meine, Sie könnten es wie folgt hacken (Beispiel von einem Kollegen oben):
Aber willst du es wirklich so machen? Es ist meistens nach einiger Zeit unlesbar, es ist, als würde man mit dem nicht gelösten Ende am Anfang des Seils beginnen.
Lambdas werden unter anderem als Einzelfunktionen in Map-, Filter- und Reduktionsfunktionen in Functional Oriented Programing verwendet. Beispiel: Zeichenwerte von Werten abrufen, die ganzzahlig und durch 2 teilbar sind
Sie können es als Funktion verwenden, indem Sie eine komplexe Funktion (oder mehr und mehrere Lambdas) definieren und in ein anderes Lambda einfügen:
Aber Python unterstützt Funktionsausdrücke auf andere Weise: -lets sagen, dass Sie eine Funktion haben, die aufgerufen wird,
superAwesomeFunction
und diese Funktion kann einige super tolle Dinge tun. Sie können sie einer Variablen zuweisen, indem Sie sie nicht aufrufen, wie folgt:Wenn Sie also SAF aufrufen, rufen Sie superAwesomeFunction oder Methode auf. Wenn Sie Ihren Lib-Ordner durchsuchen, werden Sie feststellen, dass die meisten Python-
__builtin__
Module so geschrieben sind. Dies geschieht, weil Sie manchmal einige Funktionen benötigen, die bestimmte Aufgaben ausführen, die für den Benutzer nicht ausreichen, aber für mehrere Funktionen erforderlich sind. Wenn Sie also die Wahl haben, dass Sie nicht zwei Funktionen mit dem Namen "superAwesomeFunction" haben können, können Sie "superAwesomeFunctionDoingBasicStuf" und "realSuperAwesomeFunction" haben und dann einfach die Variable "realSuperAwesomeFunction" in die Variable "superAwesomeFunction" einfügen und fertig.Sie können den Speicherort der importierten Module finden, indem Sie in die Konsole eingeben
importedModule.__file__
(reales Beispielimport os;os.__file__
). Folgen Sie diesem Verzeichnis einfach zu der Datei mit dem Namen importiertesModul.py, öffnen Sie sie im Editor und finden Sie heraus, wie Sie Ihr eigenes "Wissen" maximieren können.Ich hoffe, das hilft Ihnen und vielleicht anderen Kollegen in Schwierigkeiten.
quelle