2017-02-23 2 views
0

Ich habe in C, C# und Java programmiert. Jetzt benutze ich Python für eine Weile, aber ich habe einige Probleme mit dem Verständnis des Variablenumfangs festgestellt, was für mich im Moment sehr verwirrend ist. Zum Beispiel:Verwirrender Variablenbereich (Verschattungsvariable vom äußeren Bereich)

def f1(): 
    print(spam) # spam magically come from outer scope. ok... 


def f2(): 
    spam = "bbb" # assignment shadows variable from outer scope (logical result of f1) 
    print(spam) # printing local spam variable 


def f3(): 
    print(spam) # ERROR: unresolved reference 'spam' 
    spam = "ccc" # in f1 function everything was fine but adding assignment AFTER 
        # printing (in opposite to f2 function) causes error in line above 


def f4(): 
    print(spam) # nothing wrong here, assignment line below is commented 
    # spam = "ccc" 

spam = "aaa" 

Warum auf der Erde Funktionen können Variablen außerhalb ihres Geltungsbereichs erreichen? Und warum Shadowing-Variable aus dem äußeren Bereich ist in Ordnung, aber nur, wenn wir es vorher nicht verwendet haben?

+1

Sind Sie sicher, dass Sie einen "nicht aufgelösten Referenzfehler" in "f3" bekommen? Ich würde erwarten, dass der Fehler "UnboundLocalError: lokale Variable" Spam "vor der Zuweisung referenziert", was eher selbsterklärend ist. – kazemakase

+0

Was passiert in 'f2' ist Ihre sich ändernde Variable' spam' von 'aaa' zu' bbb' – mtkilic

+0

@kazemakase Sie haben Recht, der Fehler, den ich geschrieben habe, stammt von IDE – user3616181

Antwort

1

Python-Code wird vor der Ausführung in Byte-Code kompiliert. Dies bedeutet, dass Python analysieren kann, wie die Funktion Variablen verwendet. Eine Variable ist entweder global oder lokal in einer Funktion, aber nicht beides und es kann nicht geändert werden.

spam ist in f1 global, weil es nie zugewiesen wird. spam ist lokal in f2, weil es zugewiesen ist. Das gleiche gilt für f3. spam ist lokal in f3 wegen spam='ccc'. Mit der Anweisung print(spam) versuchen Sie, auf die lokale Variable zuzugreifen, bevor sie zugewiesen wurde.

Sie können global spam innerhalb einer Funktion verwenden, um einen Variablennamen zwingend als global zu deklarieren.

Lokal bleibt lokal. Auch nach einer Variable in der lokalen Namensraum löschen Python sieht nicht den Namen in der übergeordneten Bereich nach oben:

spam = 123 

def f(): 
    spam = 42 
    print(spam) # 42 
    del spam 
    print(spam) # UnboundLocalError 

f() 

Wenn Sie eine globale Variable zuweisen möchten, müssen Sie es erklären:

spam = 123 

def f(): 
    global spam 
    spam = 42 
    print(spam) # 42 

f() 
print(spam) # 42 
+0

Oh, ich habe vergessen, dass sogar viele Leute sagen, dass Python direkt aus dem Skript interpretiert wird, das es tatsächlich eine Kompilierungsphase hat. – user3616181

+0

Aber warum Funktionen können äußere Variablen erreichen? Was ist die Idee dahinter? Weil jemand zu dem Schluss kommen musste, dass es ein wünschenswertes Verhalten ist – user3616181

+0

@ user3616181 Da in Python gibt es keinen Unterschied zwischen Variablen, Funktionen und anderen Objekten. Sie möchten in Ihrer Funktionsdefinition 'print' aufrufen können, oder? 'print' ist ein globales Objekt und so auch' spam'. "Spam" könnte auch eine Funktion sein, die Sie in Ihrer anderen Funktion aufrufen möchten. Es gibt einfach keinen Grund, die globale Suche nicht zuzulassen. Ich habe einmal darüber nachgedacht, diese Funktion zu deaktivieren, aber dies stellte sich als [schlechte Idee] heraus (http://stackoverflow.com/a/31023487/3005167). – kazemakase

Verwandte Themen