Suche…


Syntax

  • global a, b, c
  • nichtlokal a, b
  • x = etwas # bindet x
  • (x, y) = etwas # bindet x und y
  • x + = etwas # bindet x. Ähnlich für alle anderen "op ="
  • del x # bindet x
  • für x in etwas: # bindet x
  • mit etwas als x: # bindet x
  • Ausnahme Ausnahme als Ex: # bindet Ex innerhalb des Blocks

Globale Variablen

In Python werden Variablen innerhalb von Funktionen genau dann als lokal betrachtet, wenn sie auf der linken Seite einer Zuweisungsanweisung oder einem anderen verbindlichen Vorkommen erscheinen. Andernfalls wird eine solche Bindung in umschließenden Funktionen bis zum globalen Umfang nachgeschlagen. Dies gilt auch dann, wenn die Zuweisungsanweisung nie ausgeführt wird.

x = 'Hi'

def read_x():
    print(x)   # x is just referenced, therefore assumed global

read_x()       # prints Hi

def read_y():
    print(y)   # here y is just referenced, therefore assumed global

read_y()       # NameError: global name 'y' is not defined

def read_y():
    y = 'Hey'  # y appears in an assignment, therefore it's local
    print(y)   # will find the local y

read_y()       # prints Hey

def read_x_local_fail():
    if False:
        x = 'Hey'  # x appears in an assignment, therefore it's local
    print(x)   # will look for the _local_ z, which is not assigned, and will not be found

read_x_local_fail()   # UnboundLocalError: local variable 'x' referenced before assignment

Normalerweise spiegelt eine Zuweisung innerhalb eines Bereichs alle äußeren Variablen desselben Namens:

x = 'Hi'

def change_local_x():
    x = 'Bye'
    print(x)
change_local_x()  # prints Bye
print(x)  # prints Hi

Wenn Sie einen Namen global deklarieren, bedeutet dies, dass für den Rest des Bereichs alle Zuweisungen zu dem Namen auf der obersten Ebene des Moduls erfolgen:

x = 'Hi'

def change_global_x():
    global x
    x = 'Bye'
    print(x)

change_global_x()  # prints Bye
print(x)  # prints Bye

Das global Schlüsselwort bedeutet, dass Zuweisungen auf der obersten Ebene des Moduls stattfinden, nicht auf der obersten Ebene des Programms. Andere Module benötigen weiterhin den üblichen gepunkteten Zugriff auf Variablen innerhalb des Moduls.

Zusammenfassend: Um zu wissen, ob eine Variable x für eine Funktion lokal ist, sollten Sie die gesamte Funktion lesen:

  1. Wenn Sie global x , ist x eine globale Variable
  2. Wenn Sie nonlocal x , gehört x zu einer einschließenden Funktion und ist weder lokal noch global
  3. Wenn Sie x = 5 oder for x in range(3) oder eine andere Bindung gefunden haben, ist x eine lokale Variable
  4. Ansonsten gehört x zu einem einschließenden Bereich (Funktionsbereich, globaler Bereich oder Builtins).

Lokale Variablen

Wenn ein Name an eine Funktion gebunden ist, kann er standardmäßig nur innerhalb der Funktion aufgerufen werden:

def foo():
    a = 5
    print(a) # ok

print(a) #  NameError: name 'a' is not defined

Kontrollfluss - Konstrukte haben keine Auswirkungen auf den Umfang (mit Ausnahme von der except ), aber variable Zugriff, der noch nicht zugewiesen wurde , ist ein Fehler:

def foo():
    if True: 
        a = 5
    print(a) # ok

b = 3
def bar():
    if False:
        b = 5
    print(b) # UnboundLocalError: local variable 'b' referenced before assignment

Übliche Bindungsoperationen sind Zuweisungen, for Schleifen und erweiterte Zuordnungen wie a += 5

Nichtlokale Variablen

Python 3.x 3.0

Python 3 hat ein neues Schlüsselwort namens nonlocal hinzugefügt. Das nichtlokale Schlüsselwort fügt dem inneren Bereich eine Bereichsüberschreibung hinzu. In PEP 3104 können Sie alles darüber lesen. Dies wird am besten anhand einiger Codebeispiele veranschaulicht. Eines der häufigsten Beispiele ist das Erstellen einer Funktion, die inkrementiert werden kann:

def counter():
    num = 0
    def incrementer():
        num += 1
        return num
    return incrementer

Wenn Sie versuchen, diesen Code auszuführen, erhalten Sie einen UnboundLocalError, da die num -Variable referenziert wird, bevor sie in der innersten Funktion zugewiesen wird. Fügen wir dem Mix nichtlokal hinzu:

def counter():
    num = 0
    def incrementer():
        nonlocal num
        num += 1
        return num
    return incrementer

c = counter()
c() # = 1
c() # = 2
c() # = 3

Grundsätzlich erlaubt Ihnen nonlocal das Zuweisen von Variablen in einem äußeren, jedoch nicht in einem globalen Bereich. Sie können also nonlocal in unserer counter Funktion verwenden, da sie dann versuchen würde, einen globalen Gültigkeitsbereich zuzuweisen. SyntaxError Sie es aus und Sie erhalten schnell einen SyntaxError . Stattdessen müssen Sie nonlocal in einer verschachtelten Funktion verwenden.

(Beachten Sie, dass die hier vorgestellte Funktionalität besser mit Generatoren implementiert wird.)

Verbindliches Vorkommen

x = 5
x += 7
for x in iterable: pass    

Jede der obigen Aussagen ist verbindlich - x wird an das mit 5 bezeichnete Objekt gebunden. Wenn diese Anweisung in einer Funktion angezeigt wird, ist x standardmäßig funktionslokal. Eine Liste der Bindeanweisungen finden Sie im Abschnitt "Syntax".

Funktionen überspringen Klassenbereich beim Nachschlagen von Namen

Klassen haben während der Definition einen lokalen Gültigkeitsbereich, aber Funktionen innerhalb der Klasse verwenden diesen Gültigkeitsbereich nicht, wenn Sie nach Namen suchen. Da Lambdas Funktionen sind und Erkenntnisse mit dem Funktionsumfang implementiert werden, kann dies zu überraschendem Verhalten führen.

a = 'global'

class Fred:
    a = 'class'  # class scope
    b = (a for i in range(10))  # function scope
    c = [a for i in range(10)]  # function scope
    d = a  # class scope
    e = lambda: a  # function scope
    f = lambda a=a: a  # default argument uses class scope
    
    @staticmethod  # or @classmethod, or regular instance method
    def g():  # function scope
        return a

print(Fred.a)  # class
print(next(Fred.b))  # global
print(Fred.c[0])  # class in Python 2, global in Python 3
print(Fred.d)  # class
print(Fred.e())  # global
print(Fred.f())  # class
print(Fred.g()) # global

Benutzer, die mit der Funktionsweise dieses Bereichs nicht vertraut sind, erwarten möglicherweise eine b class von b , c und e .


Ab PEP 227 :

Namen im Klassenbereich sind nicht zugänglich. Namen werden im innersten einschließenden Funktionsumfang aufgelöst. Wenn eine Klassendefinition in einer Kette verschachtelter Bereiche auftritt, überspringt der Auflösungsprozess Klassendefinitionen.

Aus der Python-Dokumentation zu Benennung und Bindung :

Der Umfang der in einem Klassenblock definierten Namen ist auf den Klassenblock beschränkt. Sie erstreckt sich nicht auf die Codeblöcke von Methoden - dies schließt Verständnis und Generatorausdrücke ein, da sie mit einem Funktionsumfang implementiert werden. Dies bedeutet, dass Folgendes fehlschlägt:

class A:
    a = 42
    b = list(a + i for i in range(10))

In diesem Beispiel werden Referenzen dieser Antwort von Martijn Pieters verwendet, die eine detailliertere Analyse dieses Verhaltens enthalten.

Der Befehl del

Dieser Befehl hat mehrere verwandte, aber unterschiedliche Formen.

del v

Wenn v eine Variable ist, entfernt der Befehl del v die Variable aus ihrem Gültigkeitsbereich. Zum Beispiel:

x = 5
print(x) # out: 5
del x
print(x) # NameError: name 'f' is not defined

Beachten Sie, dass del ein verbindliches Vorkommen ist. Dies bedeutet, dass, wenn nicht ausdrücklich anders angegeben ( nonlocal oder global ), del v v lokalen Bereich lokal wird. Wenn Sie v in einem äußeren Bereich löschen nonlocal v , verwenden Sie nonlocal v oder global v im gleichen Geltungsbereich der del v Anweisung.

In allen folgenden Fällen handelt es sich bei der Absicht eines Befehls um ein Standardverhalten, das jedoch nicht von der Sprache erzwungen wird. Eine Klasse kann so geschrieben werden, dass diese Absicht ungültig wird.

del v.name

Dieser Befehl löst einen Aufruf an v.__delattr__(name) .

Die Absicht ist , das Attribut zu machen name nicht verfügbar. Zum Beispiel:

class A:
    pass

a = A()
a.x = 7
print(a.x) # out: 7
del a.x
print(a.x) # error: AttributeError: 'A' object has no attribute 'x'

del v[item]

Dieser Befehl löst einen Aufruf an v.__delitem__(item) .

Die Absicht ist, dass das item nicht in das vom Objekt v implementierte Mapping gehört. Zum Beispiel:

x = {'a': 1, 'b': 2}
del x['a']
print(x) #  out: {'b': 2}
print(x['a']) # error: KeyError: 'a'

del v[a:b]

Dies nennt tatsächlich v.__delslice__(a, b) .

Die Intention ist der oben beschriebenen ähnlich, jedoch mit Slices - Artikelbereiche statt eines einzelnen Artikels. Zum Beispiel:

x = [0, 1, 2, 3, 4]
del x[1:3]
print(x) #  out: [0, 3, 4]

Siehe auch Garbage Collection # Der Befehl del .

Lokaler vs Globaler Geltungsbereich

Was ist lokal und global?

Alle Python-Variabes, auf die an einer bestimmten Stelle im Code zugegriffen werden kann, liegen entweder im lokalen oder im globalen Bereich .

Die Erklärung ist, dass der lokale Bereich alle Variablen umfasst, die in der aktuellen Funktion definiert sind, und der globale Bereich enthält Variablen, die außerhalb der aktuellen Funktion definiert sind.

foo = 1  # global

def func():
    bar = 2  # local
    print(foo)  # prints variable foo from global scope
    print(bar)  # prints variable bar from local scope

Man kann prüfen, welche Variablen in welchem ​​Umfang sind. Integrierte Funktionen locals() und globals() geben den gesamten Gültigkeitsbereich als Wörterbücher zurück.

foo = 1

def func():
    bar = 2
    print(globals().keys())  # prints all variable names in global scope
    print(locals().keys())  # prints all variable names in local scope

Was passiert bei Namenskonflikten?

foo = 1

def func():
    foo = 2  # creates a new variable foo in local scope, global foo is not affected

    print(foo)  # prints 2

    # global variable foo still exists, unchanged:
    print(globals()['foo'])  # prints 1
    print(locals()['foo'])  # prints 2

Verwenden Sie das Schlüsselwort global um eine globale Variable zu ändern:

foo = 1

def func():
    global foo
    foo = 2  # this modifies the global foo, rather than creating a local variable

Der Geltungsbereich ist für den gesamten Körper der Funktion definiert!

Das bedeutet, dass eine Variable für eine Hälfte der Funktion niemals global und danach lokal ist oder umgekehrt.

foo = 1

def func():
    # This function has a local variable foo, because it is defined down below.
    # So, foo is local from this point. Global foo is hidden.

    print(foo) # raises UnboundLocalError, because local foo is not yet initialized
    foo = 7
    print(foo)

Ebenso das Gegenteil:

foo = 1

def func():
    # In this function, foo is a global variable from the begining

    foo = 7  # global foo is modified

    print(foo)  # 7
    print(globals()['foo'])  # 7

    global foo  # this could be anywhere within the function
    print(foo)  # 7

Funktionen innerhalb von Funktionen

In Funktionen können viele Ebenen von Funktionen verschachtelt sein, aber innerhalb einer Funktion gibt es nur einen lokalen Gültigkeitsbereich für diese Funktion und den globalen Gültigkeitsbereich. Es gibt keine Zwischenbereiche.

foo = 1

def f1():
    bar = 1

    def f2():
        baz = 2
        # here, foo is a global variable, baz is a local variable
        # bar is not in either scope
        print(locals().keys())  # ['baz']
        print('bar' in locals())  # False
        print('bar' in globals())  # False

    def f3():
        baz = 3
        print(bar)  # bar from f1 is referenced so it enters local scope of f3 (closure)
        print(locals().keys())  # ['bar', 'baz']
        print('bar' in locals())  # True
        print('bar' in globals())  # False

    def f4():
        bar = 4  # a new local bar which hides bar from local scope of f1
        baz = 4
        print(bar)
        print(locals().keys())  # ['bar', 'baz']
        print('bar' in locals())  # True
        print('bar' in globals())  # False

global vs. nonlocal (nur Python 3)

Diese beiden Schlüsselwörter werden verwendet, um auf Variablen zuzugreifen, die für die aktuellen Funktionen nicht lokal sind.

Das global Schlüsselwort gibt an, dass ein Name als globale Variable behandelt werden soll.

foo = 0  # global foo

def f1():
    foo = 1  # a new foo local in f1
    
    def f2():
        foo = 2  # a new foo local in f2
        
        def f3():
            foo = 3  # a new foo local in f3
            print(foo)  # 3
            foo = 30  # modifies local foo in f3 only
        
        def f4():
            global foo
            print(foo)  # 0
            foo = 100  # modifies global foo

nonlocal (siehe Nichtlokale Variablen ), verfügbar in Python 3, nimmt eine lokale Variable aus einem umschließenden Bereich in den lokalen Bereich der aktuellen Funktion.

Aus der Python-Dokumentation zu nonlocal :

Die nichtlokale Anweisung bewirkt, dass die aufgelisteten Bezeichner auf zuvor gebundene Variablen im nächsten umgebenden Bereich mit Ausnahme von Globals verweisen.

Python 3.x 3.0
def f1():
    
    def f2():
        foo = 2  # a new foo local in f2

        def f3():
            nonlocal foo  # foo from f2, which is the nearest enclosing scope
            print(foo)  # 2
            foo = 20  # modifies foo from f2!


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow