Der Abschluss besteht darin, unterschiedliche Ergebnisse basierend auf unterschiedlichen Konfigurationsinformationen zu erhalten. Lassen Sie mich in diesem Artikel zwei Anmerkungen zu Python-Abschlüssen mit Ihnen teilen:
Was ist ein Abschluss?
Einfach Der Abschluss besteht darin, unterschiedliche Ergebnisse basierend auf unterschiedlichen Konfigurationsinformationen zu erhalten.
Werfen wir einen Blick auf die professionelle Erklärung: „Closure“ ist die Abkürzung für Lexical Closure, ein , der sich auf eine freie variable Funktion bezieht. Die referenzierte freie Variable verbleibt bei der Funktion, auch nachdem sie die Umgebung, in der sie erstellt wurde, verlassen hat. Daher kann man auch anders sagen, dass ein Abschluss eine Entität ist, die aus einer Funktion und der zugehörigen Referenzumgebung besteht.
Lazy Binding Externe freie Variablen, auf die von Python-Abschlussfunktionen verwiesen wird, werden träge gebunden.
Python
Wie im obigen Code gezeigt: i ist eine freie Variable im externen Bereich, auf die von der Abschlussfunktion verwiesen wird, was nur geschieht, wenn dieIn [2]: def multipliers(): ...: return [lambda x: i * x for i in range(4)] In [3]: print [m(2) for m in multipliers()] [6, 6, 6, 6] In [2]: def multipliers(): ...: return [lambda x: i * x for i in range(4)] In [3]: print [m(2) for m in multipliers()] [6, 6, 6, 6]
heißt und sucht nach dem Wert der -Variablen i. Da die -Schleife beendet ist und i auf den Endwert 3 zeigt, erhält jeder Funktionsaufruf das gleiche Ergebnis.
Lösung:1) Sofort binden, wenn die Abschlussfunktion generiert wird (
Verwenden Sie den Standardwert der Funktion Wie der obige Code: Wenn Sie eine Abschlussfunktion generieren, können Sie sehen, dass jede Abschlussfunktion einen Parameter mit einem Standardwert hat: i = i. Erklären Sie zu diesem Zeitpunkt The Der Compiler findet den Wert von i und weist ihn dem formalen Parameter i zu. Auf diese Weise wird im äußeren Bereich der generierten Abschlussfunktion (dh in der äußeren Schleife) die Variable i gefunden und ihr aktueller Wert ist dem Formalparameter i zugeordnet.In [5]: def multipliers(): return [lambda x, i=i: i* x for i in range(4)] ...: In [6]: print [m(2) for m in multipliers()] [0, 2, 4, 6] In [5]: def multipliers(): return [lambda x, i=i: i* x for i in range(4)] ...: In [6]: print [m(2) for m in multipliers()] [0, 2, 4, 6]
2) Verwenden Sie functools.partial:
Python
Wie der obige Code: Wenn aufgrund einer verzögerten Bindung Probleme auftreten können, können Sie functools verwenden. „partial“ konstruiert eine Teilfunktion, sodass die freien Variablen zunächst an die Abschlussfunktion gebunden werden.In [26]: def multipliers(): return [functools.partial(lambda i, x: x * i, i) for i in range(4)] ....: In [27]: print [m(2) for m in multipliers()] [0, 2, 4, 6] In [26]: def multipliers(): return [functools.partial(lambda i, x: x * i, i) for i in range(4)] ....: In [27]: print [m(2) for m in multipliers()] [0, 2, 4, 6]
Neubindung referenzierter freier Variablen innerhalb einer Abschlussfunktion verbietenPython
Oben Der Code meldet eine Fehler, UnboundLocalError: Auf die lokale Variable „free_value“ wird vor der Zuweisung verwiesen. Der obige Code soll einen Initialisierungs-def foo(func): free_value = 8 def _wrapper(*args, **kwargs): old_free_value = free_value #保存旧的free_value free_value = old_free_value * 2 #模拟产生新的free_value func(*args, **kwargs) free_value = old_free_value return _wrapper def foo(func): free_value = 8 def _wrapper(*args, **kwargs): old_free_value = free_value #保存旧的free_value free_value = old_free_value * 2 #模拟产生新的free_value func(*args, **kwargs) free_value = old_free_value return _wrapper
(free_value) implementieren, kann aber bei Bedarf verwendet werden, wenn die interne Abschlussfunktion ausgeführt wird neuer Zustand (free_value = old_free_value * 2), aber aufgrund der internen Neubindung behandelt der Interpreter free_value als lokale Variable. Wenn old_free_value = free_value, wird ein Fehler gemeldet, da der Interpreter denkt, dass free_value keinen Wert zugewiesen hat .
Lösung:Wenn Sie planen, die von der Abschlussfunktion referenzierte freie Variable zu ändern, können Sie sie in eine Liste einfügen, also free_value = [8], free_value kann nicht geändert werden, free_value[0] kann jedoch
sichergeändert werden. Darüber hinaus hat Python 3.x das Schlüsselwort nonlocal hinzugefügt, das dieses Problem ebenfalls lösen kann.
[Verwandte Empfehlungen]
1.
Python kostenloses Video-TutorialPython-LernhandbuchPython-objektorientiertes Video-TutorialDas obige ist der detaillierte Inhalt vonWas ist ein Abschluss? Zwei Lösungen für Probleme mit Python-Abschlüssen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!