Le site Python-Namensauflösung kennt nur die folgenden Arten von Geltungsbereichen:
- eingebauten Bereich, der die Eingebaute Funktionen , wie zum Beispiel
print
, int
, oder zip
,
- Modul globalen Bereich, der immer die oberste Ebene des aktuellen Moduls ist,
- drei benutzerdefinierte Bereiche, die ineinander verschachtelt werden können, nämlich
- Funktion Abschlussbereich, von jedem umschließenden
def
Block, lambda
Ausdruck oder Verstehen.
- Funktion lokalen Bereich, innerhalb einer
def
Block, lambda
Ausdruck oder Verstehen,
- Klasse Bereich, innerhalb eines
class
Block.
Vor allem andere Konstrukte wie if
, for
, oder with
Anweisungen haben keinen eigenen Geltungsbereich.
Das Scoping TLDR : Die Nachschlagen eines Namens beginnt mit dem Bereich, in dem der Name verwendet wird, dann alle umgebenden Bereiche (mit Ausnahme der Klassenbereiche), die Modulglobals und schließlich die Builtins - die erste Übereinstimmung in dieser Suchreihenfolge wird verwendet. Die Auftrag auf einen Bereich bezieht sich standardmäßig auf den aktuellen Bereich - die Sonderformen nonlocal
y global
muss verwendet werden, um zuweisen. zu einem Namen aus einem äußeren Bereich.
Schließlich können auch Comprehensions und Generatorausdrücke sowie :=
Zuordnungsausdrücke haben eine besondere Regel, wenn sie kombiniert werden.
Verschachtelte Geltungsbereiche und Namensauflösung
Diese verschiedenen Geltungsbereiche bilden eine Hierarchie, wobei Builtins und Global immer die Basis bilden und Closures, Locals und Class Scope als lexikalisch definiert. Das heißt, dass nur die Verschachtelung im Quellcode von Bedeutung ist, nicht aber z. B. der Aufrufstapel.
print("builtins are available without definition")
some_global = "1" # global variables are at module scope
def outer_function():
some_closure = "3.1" # locals and closure are defined the same, at function scope
some_local = "3.2" # a variable becomes a closure if a nested scope uses it
class InnerClass:
some_classvar = "3.3" # class variables exist *only* at class scope
def nested_function(self):
some_local = "3.2" # locals can replace outer names
print(some_closure) # closures are always readable
return InnerClass
Auch wenn class
erzeugt einen Bereich und kann verschachtelte Klassen, Funktionen und Comprehensions haben, wobei die Namen der class
Bereich sind für eingeschlossene Bereiche nicht sichtbar. Dadurch entsteht die folgende Hierarchie:
builtins [print, ...]
globals [some_global]
outer_function [some_local, some_closure]
InnerClass [some_classvar]
inner_function [some_local]
Die Namensauflösung beginnt immer mit dem derzeitiger Anwendungsbereich in dem ein Name aufgerufen wird, und geht dann in der Hierarchie nach oben, bis eine Übereinstimmung gefunden wird. Zum Beispiel, wenn Sie some_local
innerhalb outer_function
y inner_function
startet bei der jeweiligen Funktion - und findet sofort die some_local
definiert in outer_function
y inner_function
. Wenn ein Name nicht lokal ist, wird er aus dem nächstgelegenen umschließenden Bereich geholt, der ihn definiert - nachschlagen some_closure
y print
innerhalb inner_function
sucht bis outer_function
bzw. Einbauten.
Bereichsdeklarationen und Namensbindungen
Standardmäßig gehört ein Name zu jedem Bereich, in dem er an einen Wert gebunden ist. Die erneute Bindung desselben Namens in einem inneren Bereich erzeugt eine neue Variable mit demselben Namen - zum Beispiel, some_local
existiert getrennt in beiden outer_function
y inner_function
. In Bezug auf den Geltungsbereich umfasst die Bindung jede Anweisung, die den Wert eines Namens festlegt - Zuweisungsanweisungen, aber auch die Iterationsvariable einer for
Schleife oder den Namen einer with
Kontext-Manager. Bemerkenswert, del
gilt auch als Namensbindung.
Wenn sich ein Name auf eine äußere Variable beziehen muss und in einem inneren Bereich gebunden werden, muss der Name als nicht lokal deklariert werden. Für die verschiedenen Arten von umschließenden Bereichen gibt es gesonderte Deklarationen: nonlocal
bezieht sich immer auf den nächstgelegenen Abschluss, und global
bezieht sich immer auf einen globalen Namen. Bemerkenswert, nonlocal
bezieht sich nie auf einen globalen Namen und global
ignoriert alle Verschlüsse mit demselben Namen. Es gibt keine Erklärung, die auf den eingebauten Bereich verweist.
some_global = "1"
def outer_function():
some_closure = "3.2"
some_global = "this is ignored by a nested global declaration"
def inner_function():
global some_global # declare variable from global scope
nonlocal some_closure # declare variable from enclosing scope
message = " bound by an inner scope"
some_global = some_global + message
some_closure = some_closure + message
return inner_function
Erwähnenswert ist, dass die Funktion local und nonlocal
werden zur Kompilierzeit aufgelöst. A nonlocal
Name muss in einem äußeren Bereich existieren. Im Gegensatz dazu ist eine global
Name kann dynamisch definiert werden und kann jederzeit zum globalen Geltungsbereich hinzugefügt oder aus diesem entfernt werden.
Umfassungen und Zuweisungsausdrücke
Die Scoping-Regeln für List-, Set- und Dict-Comprehensions und Generatorausdrücke sind fast dasselbe wie für Funktionen. Ebenso lauten die Scoping-Regeln für Zuweisungsausdrücke fast wie bei der normalen Namensbindung.
Der Geltungsbereich von Comprehensions und Generatorausdrücken ist derselbe wie der von Funktionen. Alle im Geltungsbereich gebundenen Namen, d. h. die Iterationsvariablen, sind lokale oder geschlossene Ausdrücke in den Geltungsbereichen von Comprehensions/Generatoren und verschachtelten Ausdrücken. Alle Namen, einschließlich der Iterationsvariablen, werden mit der Namensauflösung aufgelöst, die auch innerhalb von Funktionen gilt.
some_global = "global"
def outer_function():
some_closure = "closure"
return [ # new function-like scope started by comprehension
comp_local # names resolved using regular name resolution
for comp_local # iteration targets are local
in "iterable"
if comp_local in some_global and comp_local in some_global
]
Eine :=
Zuweisungsausdruck wirkt auf die nächste Funktion, Klasse oder den nächsten globalen Bereich. Insbesondere, wenn das Ziel eines Zuweisungsausdrucks deklariert wurde nonlocal
o global
im nächstgelegenen Bereich, der Zuweisungsausdruck honoriert dies wie eine reguläre Zuweisung.
print(some_global := "global")
def outer_function():
print(some_closure := "closure")
Ein Zuweisungsausdruck innerhalb einer Comprehension/eines Generators arbeitet jedoch mit der nächstgelegenen umschließender Geltungsbereich des Verstehens/Generierens, nicht des Geltungsbereichs des Verstehens/Generierens selbst. Wenn mehrere Comprehensions/Generatoren verschachtelt sind, wird der nächstgelegene Funktions- oder globale Bereich verwendet. Da der Bereich der Comprehension/des Generators Closures und globale Variablen lesen kann, ist die Zuweisungsvariable auch in der Comprehension lesbar. Eine Zuweisung aus einer Comprehension in einen Klassenbereich ist nicht zulässig.
print(some_global := "global")
def outer_function():
print(some_closure := "closure")
steps = [
# v write to variable in cotaining scope
(some_closure := some_closure + comp_local)
# ^ read from variable in containing scope
for comp_local in some_global
]
return some_closure, steps
Während die Iterationsvariable lokal in der Comprehension ist, in der sie gebunden ist, erstellt das Ziel des Zuweisungsausdrucks keine lokale Variable und wird aus dem äußeren Bereich gelesen:
builtins [print, ...]
globals [some_global]
outer_function [some_closure]
<listcomp> [comp_local]
4 Stimmen
Die Geltungsbereichsregeln werden ziemlich knapp, aber auch vollständig, in der Python-Dokumentation beschrieben: docs.python.org/3/reference/….