Scopes in Python (Gültigkeitsbereiche) (C) 2017-2021 T.Birnthaler OSTC GmbH ====================================== Folgende LEGB-Regel gilt bezügliche der REIHENFOLGE der durchsuchten Scopes (Gültigkeitsbereiche) bei einem "Name-Lookup" von oben nach unten. Beim ersten Treffer ist die Suche zu Ende: +------------+-------------------------------------------+ || | L)ocal | Funktion (auch Lambda) | || | E)nclosing | Einschachtelnde Funktion (z.B. Dekorator) | || | G)lobal | Hauptprogramm (Modul) | || | B)uilt-in | Python-Interpreter (z.B. len, sum, abs) | || +------------+-------------------------------------------+ \/ ACHTUNG: Es gibt KEINE Block-lokalen Namen in Python (KEINE Block-Scopes, Blöcke werden durch gleichförmiges Einrücken nach einem ":" gebildet. Auch Laufvariablen von for-Schleifen sind global (und enthalten den letzten erreichten Wert): var = 0 # var ist globale Variable for i in range(1,10+1): # i ist globale Variable j = 10 # j ist globale Variable var += i # var, i sind globale Variable print(var, i, j) # var, i, j sind globale Variable Folgendes Code-Stück zeigt dieses LEGB-Verhalten beim "Name-Lookup" (R = Ausgabe-Reihenfolge) +------------------------+--------------------+---+-------------------------+ | Code | Aktion | R | Ausgabe | +------------------------+--------------------+---+-------------------------+ | print(len) | | 1 | | | def f_aussen(): | Def. Funktion | | | | len = "E)nclosing" | Def. lok. Var. | | | | print(len) | | 3 | E)nclosing | | def f_innen(): | Def. Funktion | | | | len = "L)okal" | Def. lok. Var. | | | | print(len) | | 5 | L)ocal | | print(len) | | 4 | E)nclosing | | f_innen() | Aufruf "f_innen" | | | | print(len) | | 6 | E)nclosing | | print(len) | | 2 | | | f_aussen() | Aufruf "f_aussen" | | | | print(len) | | 7 | | | len = "G)lobal" | Def. glob. Var. | | | | print(len) | | 8 | G)lobal | | del len | Löschen glob. Var. | | | | print(len) | | 9 | | +------------------------+--------------------+---+-------------------------+ Auf eine GLOBALE Variable kann in Funktionen LESEND zugegriffen werden, falls keine gleichnamige LOKALE Variable durch Zuweisung gebildet wird: gv = "global" # Globale Variable gv erzeugen # def f(...): # Funktion f() definieren print(gv) # Globale Variable gv lesen (OK) # def g(...): # Funktion g() definieren gv = 123 # Lokale Variable gv erzeugen (OK, gleichnamig) print(gv) # Lokale Variable gv lesen (OK) Erst eine globale Variable LESEN und dann eine gleichnamige lokale Variable ERZEUGEN ist nicht erlaubt (erzeugt den Fehler "UnboundLocalError" mit der Meldung "local variable 'gv' referenced before assignment): def g(...): # Funktion g() definieren print(gv) # Globale Variable gv lesen (OK) gv = 123 # Lokale Variable gv erzeugen (PENG, gleichnamig) Per Schlüsselwort "global" kann eine Funktion auf einen GLOBALEN Namen des Hauptprogramms LESEND + SCHREIBEND zugreifen (diese "Schweinerei" wird also durch das Schlüsselwort "global" deutlich sichtbar gemacht): gv = "global" # Globale Variable gv erzeugen # def f(...): # Funktion f() definieren global gv # Globale Variable gv lesen + schreiben erlauben print(gv) # Globale Variable gv lesen (OK) gv = "lokal" # Globale Variable gv schreiben (OK) print(gv) # Globale Variable gv lesen (OK) Per Schlüsselwort "nonlocal" kann eine Funktion auf einen LOKALEN Namen der direkt umgebenden "Wrapper"-Funktion zugreifen (LESEN + SCHREIBEN). Dies ist auch mehrfach bei mehrfach verschachtelten Funktionen möglich: def f(...): # Funktion f() definieren lv = "lokal" # Lokale Variable lv erzeugen # def g(...): # Eingeschachtelte (lokale) Funktion g() definieren nonlocal lv # Nichtlokale Variable lv von f() verwenden print(lv) # Nichtlokale Variable lv von f() lesen (OK) lv = "lokal" # Nichtlokale Variable lv von f() schreiben (OK) print(lv) # Nichtlokale Variable lv von f() lesen (OK)