2016-12-26 1 views
0

Dieses Skript definiert eine Variable in main(), aber die Variable steht nicht zur Verfügung func(), die in main() ausgeführt wird. Warum das?Variable nicht verfügbar für Unterfunktion

#!/usr/bin/env python3 
# vars_in_func.py 
# Test script for variables within a function. 

def func(): 
    print(greeting) 

def main(): 
    greeting = "Hello world" 
    func() 

main() 

Fehler:

Traceback (most recent call last): 
    File "./vars_in_func.py", line 11, in <module> 
    main() 
    File "./vars_in_func.py", line 9, in main 
    func() 
    File "./vars_in_func.py", line 5, in func 
    print(greeting) 
NameError: name 'greeting' is not defined 

Wenn ich das Skript Python2 konvertieren, der Fehler ist das gleiche, außer es sagt global name statt name.

Ich nehme an, ich vermisse nur ein Schlüsselkonzept. Ich habe gerade angefangen, Python zu lernen, nachdem ich Bash gelernt habe.

Bearbeiten: Nachdem ich die Antworten gelesen hatte, erkannte ich meinen Fehler: Ich denke immer noch in Bash, wo Funktionen entweder in der gleichen Shell wie der Aufrufer (mit den gleichen Variablen) oder eine Unterschale von der Aufrufer (vererbte Variablen).

+2

Lesen Sie über [Scope-Regeln] (http://stackoverflow.com/questions/291978/short-description-of-scoping-rules) – trincot

+2

'func' läuft nicht innerhalb' main() '". Es wird nur von 'main' aufgerufen. Das bedeutet nicht, dass es lokale Variablen in 'main' sieht. – BrenBarn

Antwort

3
greeting = None 

def func(): 
    print(greeting) 

def main(): 
    global greeting 
    greeting = "Hello world" 
    func() 

main() 

In Ihrer Lösung ist die in der Hauptfunktion definierte Begrüßung eine lokale Variable, auf die außerhalb der Hauptfunktion nicht zugegriffen werden kann. das ist der Grund, warum es Ihnen Fehler gab

+0

Können Sie erklären, warum Sie die Begrüßung als global innerhalb der Hauptmethode markieren müssen? Wenn man es auslässt, führt das zu einem schlechten Mojo. – Irisshpunk

+0

Begrüßung ist in der Funktion 'main()' als global markiert, da sie dort * modifiziert * ist. In der Funktion 'func()' ist sie nicht global markiert, da sie dort * nur referenziert * nicht modifiziert ist. Klar? –

0

In Python können Funktionen auf keine Variable außerhalb der Funktion zugreifen, außer es ist ein Parameter oder global deklariert.

Dies sollte hoffentlich das Problem beheben:

greeting = None 

def func(): 
    print(greeting) 

def main(): 
    global greeting # Declaring as global means func() can access it 
    greeting = "Hello world" 
    func() 

main() 
+0

Das stimmt nicht ganz. Eine Funktion kann * auf * globale Variablen zugreifen, aber sie kann * ihnen * nicht zuweisen, es sei denn, sie werden innerhalb des Gültigkeitsbereichs der Funktion als 'global' deklariert. – ekhumoro

2

Ich weiß nicht viel über Python, aber im Allgemeinen brauchen globale Variablen außerhalb des Bereichs der Haupt aber vor der Funktion, die Sie sie verwenden möchten definiert werden in Wenn Sie keine Variable global machen wollen, müssen Sie die Variable als Parameter an die Funktion übergeben.

0

Siehe this post.

In Python hat jede Funktion ihren eigenen Gültigkeitsbereich, so dass Sie außerhalb der Funktion 'main' nicht auf die Variable 'greetings' zugreifen können, da sie innerhalb dieser Funktion definiert wurde.

1

Es gibt viele Antworten zu Python-Scoping-Regeln, und hier kommt es wirklich darauf an. Aber wie ich Ihre Frage sehe, besteht Ihr Missverständnis in etwas völlig anderem: ein riesiger Unterschied zwischen der Definition der Funktion und dem Aufruf.

LEGB Regel ist wichtig, aber was wirklich wichtig ist hier, dass: „Scopes statisch bestimmt werden, sie sahen sich dynamisch nach oben“ . Grob gesagt weiß die Funktion, wo nach der Variable gesucht werden soll (wenn kompiliert), kennt aber nicht den Variablenwert (bevor Sie die Funktion aufrufen).

In Ihrem Fall rufen Sie einfach eine Funktion in den Körper einer anderen Funktion. Wenn Sie eine Funktion aufrufen, übergibt der Aufrufer die Kontrolle an den Aufgerufenen (stellen Sie sich das grob als Sprung in Ihrem Quellcode zum Anfang des Codeblocks der Funktion vor). Also, wenn Sie func anrufen, springen Sie in func Körper. Diese Funktion versucht, Namen zu finden: print und greeting (dieser Vorgang wird Name resolution genannt) sieht es in local Umfang, dann in global Umfang (der Anwendungsbereich, wo er definiert wurde, nicht genannt) und schließlich in builtins.Es findet nur print in builtins. Da greeting Name nicht gefunden wurde, wird eine Ausnahme NameError ausgelöst (Ausnahme wird an dem Punkt ausgelöst, an dem der Fehler erkannt wird) in Ihrem Fall an der Stelle, wo mainfunc genannt wird. Und wenn eine Ausnahme überhaupt nicht behandelt wird, beendet der Interpreter die Ausführung des Programms oder kehrt zu seiner interaktiven Hauptschleife zurück. In beiden Fällen wird ein Stack-Backtrace ausgegeben, außer wenn die Ausnahme SystemExit ist.

Ich hoffe, es wird einige Punkte für Sie klären.

Ein weiterer Ort, nach Informationen zu suchen: The Python Language Reference: Execution model

P. S .: die global scope ist immer module (Datei mit Code), wo Funktion definiert wurde. Es ist sehr wichtig zu verstehen !!!

Verwandte Themen