Heim  >  Artikel  >  Backend-Entwicklung  >  Wie gehe ich mit Problemen beim Variablenbereich in nicht verschachtelten Lambda-Abschlüssen um?

Wie gehe ich mit Problemen beim Variablenbereich in nicht verschachtelten Lambda-Abschlüssen um?

Barbara Streisand
Barbara StreisandOriginal
2024-10-21 13:10:03594Durchsuche

How to Handle Variable Scoping Issues in Non-Nested Lambda Closures?

Python Lambda Closure Scoping

Problem

Variablen in Abschlüssen zu kapseln, um sie aus Funktionssignaturen zu entfernen, ist eine Technik, die häufig für eine effiziente Codestrukturierung verwendet wird. Bei nicht verschachtelten Lambdas behält der Abschluss jedoch den Endwert der Variablen bei, was zu Problemen führt, wenn versucht wird, auf bestimmte Werte basierend auf der iterierenden Variablen zuzugreifen.

Beachten Sie den bereitgestellten Codeausschnitt:

names = ['a', 'b', 'c']

def test_fun(name, x):
    print(name, x)

def gen_clousure(name):
    return lambda x: test_fun(name, x)

funcs1 = [gen_clousure(n) for n in names]
funcs2 = [lambda x: test_fun(n, x) for n in names]

# Expected output for funcs1
for f in funcs1:
    f(1)

# Unexpected output for funcs2 (returns last element for all cases)
for f in funcs2:
    f(1)

Das Verständnis des Grundes für diese Diskrepanz ist entscheidend für eine effektive Schließungsnutzung.

Antwort

Das grundlegende Konzept in dieser Situation ist variables Scoping in Schließungen . Abschlüsse enthalten von Natur aus die Variablennamen und nicht ihre Werte. Dies bedeutet, dass die Auswertung der Variablen erfolgt, wenn die Lambda-Ausführung beginnt, und nicht zum Zeitpunkt der Lambda-Definition.

Im Fall von funcs2, wenn Sie Lambda x: test_fun(n, x) ausführen, wird die Variable n wird bei der Lambda-Definition nicht bewertet. Stattdessen erfolgt die Auswertung nur beim Lambda-Aufruf. Zu diesem Zeitpunkt enthält n den letzten Wert aus der Schleife (in diesem Fall „c“). Folglich verwendet die Funktion f immer „c“ als Wert von n, unabhängig von der Eingabe x.

Um dieses Problem zu beheben und die gewünschte Funktionalität zu erreichen, muss die Variable n im Gültigkeitsbereich der Lambda-Funktion erfasst werden. Dies kann erreicht werden, indem die Variable als Argument an das Lambda übergeben wird, wie im Folgenden dargestellt:

funcs2 = [lambda x: test_fun(n, x) for n in names if 2 > 0]

Durch die Einbindung dieser zusätzlichen if-Anweisung, die immer wahr ist, erzwingen wir Das Lambda nimmt den Wert von n als Argument und stellt so das erwartete personalisierte Verhalten in allen Fällen sicher.

Alternative mit Wrapped Lambda

Alternativ können Sie das nicht verschachtelte Lambda in ein verschachteltes verpacken Funktion, die den Zugriff auf nicht deklarierte Variablen im Bereich effektiv verhindert. Der folgende Code veranschaulicht diesen Ansatz:

def makeFunc(n):
    return lambda x: x+n

stuff = [makeFunc(n) for n in [1, 2, 3]]

for f in stuff:
    print(f(1))

Hier wird die Variable n in der Funktion makeFunc erfasst, um den richtigen Bereich innerhalb des Lambda sicherzustellen.

Fazit

Verstehen und Die Verwaltung des Variablenbereichs in Abschlüssen ist für ein effektives Codedesign und Debugging von entscheidender Bedeutung. Die wichtigsten Erkenntnisse sind:

  • Abschlüsse enthalten Variablennamen, keine Werte
  • Variablenauswertung erfolgt während der Lambda-Ausführung
  • Um Variablen zu erfassen, übergeben Sie sie entweder als Argumente oder wickeln sie ein das Lambda in einer anderen Funktion

Das obige ist der detaillierte Inhalt vonWie gehe ich mit Problemen beim Variablenbereich in nicht verschachtelten Lambda-Abschlüssen um?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn