483 Stimmen

Nichtlokale Python-Anweisung

Was bedeutet die Python nonlocal Anweisung tun (in Python 3.0 und höher)?

Es gibt keine Dokumentation auf der offiziellen Python-Website und help("nonlocal") funktioniert ebenfalls nicht.

664voto

Anon Punkte 11126

Vergleichen Sie dies, ohne die Verwendung von nonlocal :

x = 0
def outer():
    x = 1
    def inner():
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# inner: 2
# outer: 1
# global: 0

Zu diesem Zweck werden nonlocal donde inner() 's x ist jetzt auch outer() 's x :

x = 0
def outer():
    x = 1
    def inner():
        nonlocal x
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# inner: 2
# outer: 2
# global: 0

Wenn wir Folgendes verwenden würden global würde es die x auf den richtigen "globalen" Wert:

x = 0
def outer():
    x = 1
    def inner():
        global x
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# inner: 2
# outer: 1
# global: 2

129voto

Arkady Punkte 12965

Kurz gesagt, können Sie damit einer Variablen in einem äußeren (aber nicht globalen) Bereich Werte zuweisen. Siehe PEP 3104 für alle blutigen Details.

56voto

Eine Google-Suche nach "python nonlocal" ergab den Vorschlag, PEP 3104 , in dem die Syntax und die Argumentation hinter der Anweisung ausführlich beschrieben werden. Kurz gesagt, sie funktioniert genauso wie die global Anweisung, mit der Ausnahme, dass sie verwendet wird, um auf Variablen zu verweisen, die weder global noch lokal für die Funktion sind.

Hier ein kurzes Beispiel dafür, was Sie damit machen können. Der Zählergenerator kann umgeschrieben werden, um dies zu verwenden, so dass er mehr wie die Idiome von Sprachen mit Abschlüssen aussieht.

def make_counter():
    count = 0
    def counter():
        nonlocal count
        count += 1
        return count
    return counter

Man könnte dies natürlich auch als Generator schreiben, etwa so:

def counter_generator():
    count = 0
    while True:
        count += 1
        yield count

Aber Dies ist zwar vollkommen idiomatisches Python, doch scheint die erste Version für Anfänger etwas offensichtlicher zu sein. Die ordnungsgemäße Verwendung von Generatoren durch den Aufruf der zurückgegebenen Funktion ist ein häufiger Punkt der Verwirrung. Die erste Version gibt explizit eine Funktion zurück.

25voto

Es wird diejenige genommen, die dem Bezugspunkt im Quellcode am nächsten liegt. Dies wird als "Lexical Scoping" bezeichnet und ist seit über 40 Jahren Standard.

Die Klassenmitglieder von Python befinden sich in Wirklichkeit in einem Wörterbuch namens __dict__ und wird niemals durch lexikalisches Scoping erreicht.

Wenn Sie nicht angeben nonlocal aber tun x = 7 eingeben, wird eine neue lokale Variable "x" erstellt. Wenn Sie angeben nonlocal findet es das "nächstgelegene" "x" und ordnet es diesem zu. Wenn Sie angeben nonlocal und kein "x" vorhanden ist, erhalten Sie eine Fehlermeldung.

Das Schlüsselwort global kam mir schon immer seltsam vor, da es alle anderen "x" bis auf das äußerste einfach ignoriert.

17voto

Yossi Truzman Punkte 179

help('nicht-lokal') Die nonlocal Anweisung


    nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*

En nonlocal Anweisung verweisen die aufgeführten Bezeichner auf zuvor gebundene Variablen im nächstgelegenen umschließenden Bereich verweisen. Dies ist wichtig, weil das Standardverhalten für die Bindung darin besteht, den lokalen Namespace zuerst durchsucht. Die Anweisung erlaubt gekapselten Code, um Variablen außerhalb des lokalen Bereichs neben dem globalen (Modul-)Bereich neu zu binden. (Modul) Bereich.

Namen, die in einer nonlocal Anweisung, im Gegensatz zu den in einer global Anweisung auf bereits bestehende Bindungen in einer umschließenden Bereich beziehen (der Bereich, in dem eine neue Bindung erstellt werden soll erstellt werden soll, kann nicht eindeutig bestimmt werden).

Namen, die in einer nonlocal Anweisung darf nicht mit der Anweisung pre- bestehenden Bindungen im lokalen Bereich kollidieren.

Siehe auch:

PEP 3104 - Zugriff auf Namen in äußeren Bereichen (Outer Scopes)
Die Spezifikation für die nonlocal Erklärung.

Verwandte Hilfethemen: global, NAMESPACES

Quelle: Python-Sprachreferenz

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X