Python Scope
Python Scope und die LEGB-Regel: lokale, umschließende, globale und eingebaute Geltungsbereiche mit klaren Beispielen und den Schlüsselwörtern global und nonlocal.
Python Scope verstehen
Scope (Geltungsbereich) bestimmt, wo ein Variablenname sichtbar ist und wie lange er existiert. Jeder Name, den Sie anlegen — eine Variable, eine Funktion, eine Klasse — gehört zu genau einem Scope. Wenn Python auf einen Namen trifft, durchsucht es die Scopes in einer festen Reihenfolge, bis es den Namen findet oder einen NameError auslöst.
Diese Seite behandelt:
- Die vier Scope-Ebenen und die LEGB-Suchregel
- Die Schlüsselwörter
globalundnonlocal - Häufige Fallstricke: Shadowing,
UnboundLocalErrorund Namensüberlappungen - Wie man Scopes zur Laufzeit untersucht
Die LEGB-Regel
Python löst Namen in vier Schichten auf, die von innen nach außen durchsucht werden:
| Ebene | Steht für | Was sie enthält |
|---|---|---|
| L | Local (Lokal) | Namen, die innerhalb der aktuellen Funktion definiert sind |
| E | Enclosing (Umschließend) | Namen in einer umgebenden (äußeren) Funktion, bei verschachtelten Funktionen |
| G | Global | Namen, die auf oberster Ebene des aktuellen Moduls definiert sind |
| B | Built-in (Eingebaut) | Von Python vorgeladene Namen — print, len, range, type usw. |
Python hält beim ersten Treffer an. Wird in keiner Schicht ein Treffer gefunden, wird ein NameError ausgelöst.
Lokaler Scope
Ein Name ist lokal, wenn er innerhalb einer Funktion zugewiesen wird. Er entsteht, wenn die Funktion aufgerufen wird, und wird zerstört, wenn die Funktion zurückkehrt. Lokale Namen sind außerhalb der Funktion nicht sichtbar.
def greet():
message = "Hello, World!" # local variable
print(message) # accessible here
greet()
# Output: Hello, World!
print(message) # NameError: name 'message' is not definedWarum der lokale Scope wichtig ist
Der lokale Scope ermöglicht es, einfache, beschreibende Namen wie total, result oder i in jeder Funktion zu verwenden, ohne dass diese miteinander oder mit Code auf Modulebene kollidieren.
def calculate_area(radius):
pi = 3.14159 # local to this function
area = pi * radius ** 2
return area
def calculate_volume(radius, height):
pi = 3.14159 # completely separate local 'pi'
volume = pi * radius ** 2 * height
return volume
print(calculate_area(5)) # 78.53975
print(calculate_volume(5, 10)) # 785.3975Beide Funktionen verwenden pi unabhängig voneinander. Es gibt keinen Konflikt.
Umschließender Scope
Wenn eine Funktion innerhalb einer anderen Funktion definiert wird, kann die innere Funktion Namen aus der äußeren (umschließenden) Funktion lesen. Das ist das E in LEGB.
def outer():
color = "blue" # enclosing variable
def inner():
print(color) # reads from enclosing scope
inner()
outer()
# Output: blueDie innere Funktion kann color ohne ein spezielles Schlüsselwort lesen, weil Python automatisch zum umschließenden Scope aufsteigt.
Eine umschließende Variable mit nonlocal ändern
Eine umschließende Variable zu lesen ist automatisch möglich, aber um ihr einen neuen Wert zuzuweisen, ist das Schlüsselwort nonlocal erforderlich. Ohne es behandelt Python die Zuweisung als Anlegen einer neuen lokalen Variable, nicht als Änderung der umschließenden Variable.
def make_counter():
count = 0 # enclosing variable
def increment():
nonlocal count # declare intent to modify the enclosing 'count'
count += 1
return count
return increment
counter = make_counter()
print(counter()) # 1
print(counter()) # 2
print(counter()) # 3Jeder Aufruf von counter() ändert dieselbe Variable count. Dieses Muster ist die Grundlage von Closures — eine ausführlichere Betrachtung finden Sie unter Python Closures.
Globaler Scope
Namen, die auf der obersten Ebene eines Moduls (außerhalb jeder Funktion) definiert sind, sind global. Sie sind von überall im selben Modul zugänglich, auch aus Funktionen heraus.
language = "Python" # global variable
def display_language():
print(language) # reads global without any keyword
display_language()
# Output: PythonEine globale Variable mit global ändern
Eine globale Variable lässt sich aus einer Funktion heraus ohne Schlüsselwort lesen. Möchten Sie ihr jedoch einen neuen Wert zuweisen, müssen Sie sie zunächst mit global deklarieren:
total = 0 # global variable
def add_to_total(n):
global total # declare intent to modify the global
total += n
add_to_total(5)
add_to_total(3)
print(total) # 8Ohne global total würde die Zeile total += n einen UnboundLocalError auslösen, weil Python total als lokale Variable behandeln würde, der noch kein Wert zugewiesen wurde.
Mehr über globale Variablen finden Sie unter Python Global Variables.
Wann man global vermeiden sollte
Die häufige Verwendung von global erschwert das Testen und das Nachvollziehen von Code. Bevorzugen Sie es, Werte aus Funktionen zurückzugeben und Daten als Argumente zu übergeben. Reservieren Sie global für echten Zustand auf Modulebene — Konfigurationsflags, Zähler oder Caches — und setzen Sie es sparsam ein.
Eingebauter Scope
Der eingebaute Scope enthält Namen, die Python automatisch bereitstellt. Sie sind in jedem Modul ohne Import verfügbar.
Häufige eingebaute Namen sind print, len, range, type, int, str, list, dict, set, tuple, open, input, max, min, sum, sorted, enumerate, zip und map.
Eingebaute Namen nicht verdecken
Da der eingebaute Scope zuletzt durchsucht wird, verdeckt jeder lokale oder globale Name mit derselben Schreibweise ihn. Das ist ein häufiger Fehler:
# Bad: shadows the built-in 'list'
list = [1, 2, 3]
print(type(list)) # <class 'list'> — still works here
new = list([4, 5]) # TypeError: 'list' object is not callableLöschen Sie den verdeckenden Namen, um den eingebauten Namen wiederherzustellen:
del list # remove the local/global shadowing name
new = list([4, 5]) # works again: [4, 5]Das eingebaute Modul ist als builtins verfügbar, falls Sie es explizit ansprechen müssen:
import builtins
print(builtins.len([1, 2, 3])) # 3Häufige Fallstricke
UnboundLocalError
Der häufigste Scope-Fehler in Python ist das Lesen eines Namens, bevor er innerhalb einer Funktion zugewiesen wird, wenn es in derselben Funktion auch eine Zuweisung zu diesem Namen gibt:
x = 10
def bad_func():
print(x) # UnboundLocalError! Python sees x = 20 below
x = 20 # this makes 'x' local for the whole function
bad_func()Python entscheidet zur Kompilierzeit, dass x lokal ist (weil es in der Funktion zugewiesen wird). Der Versuch, es vor der Zuweisung zu lesen, löst UnboundLocalError: local variable 'x' referenced before assignment aus.
Beheben Sie das, indem Sie entweder global x deklarieren oder x innerhalb der Funktion nicht zuweisen.
Variable Shadowing (Namensverdeckung)
Eine lokale Variable, die denselben Namen wie eine globale hat, verdeckt die globale Variable stillschweigend. Das ist normalerweise beabsichtigt, kann aber zu subtilen Fehlern führen, wenn Sie erwarten, die globale Variable zu lesen:
x = 10 # global
def my_func():
x = 20 # local — shadows the global
print(x) # 20, not 10
my_func()
print(x) # 10 — global unchangedScope zur Laufzeit untersuchen
Python macht den aktuellen Scope-Inhalt über zwei eingebaute Funktionen zugänglich.
locals() gibt ein Dictionary des aktuellen lokalen Scopes zurück (oder den Namespace auf Modulebene, wenn es auf der obersten Ebene aufgerufen wird):
def show_locals():
a = 1
b = "hello"
print(locals()) # {'a': 1, 'b': 'hello'}
show_locals()globals() gibt das globale (modulweite) Namespace-Dictionary zurück:
language = "Python"
print("language" in globals()) # TrueDiese Funktionen sind nützlich für Debugging und Introspektion, sollten aber nicht verwendet werden, um Variablen in Produktionscode dynamisch zu manipulieren.
Scope und Funktionen
Funktionen in Python sind Objekte und selbst Namen, die in einem Scope leben. Eine Funktion, die am Anfang eines Moduls definiert wird, ist global; eine Funktion, die innerhalb einer anderen Funktion definiert wird, ist lokal für die umschließende Funktion.
def outer():
def helper(): # helper is local to outer
return 42
return helper()
print(outer()) # 42
# helper() # NameError: helper is not defined hereInformationen dazu, wie Funktionen definiert werden, finden Sie unter Python Functions; anonyme Funktionen, die ebenfalls der LEGB-Regel gehorchen, werden unter Python Lambda behandelt.
Kurzreferenz
| Schlüsselwort | Wirkung |
|---|---|
| (keines) | Lesen aus dem nächstgelegenen umschließenden Scope per LEGB-Suche |
global x | Teilt der aktuellen Funktion mit, dass x auf den Namen auf Modulebene verweist |
nonlocal x | Teilt der aktuellen Funktion mit, dass x auf den Namen in der nächstgelegenen umschließenden Funktion verweist |