2017-06-09 2 views
3

Ich bin neu im Programmieren und überfliege einige Themen zu Funktionen und Klassen. Nach dem Lesen von Funktionen und umschließenden Funktionen habe ich versucht, die Vererbung in Klassen nachzuahmen, indem ich nur Funktionen und deren Umfang minipuliere.Umschließende Funktionen Scope Search?

Beispiel:

für den Code

def f1(): 
    t=1 
    def f2(x): 
     return eval(x) 
    return f2 

Warum ich einen Namen Fehlermeldung erhalten Sie, wenn

f1()('t') #expecting 1 return

zu tun, aber nicht, wenn

def f1(): 
    t=1 
    def f2(): 
     return t 
    return f2 
sagen definieren

Ich könnte dieses Problem lösen, indem ich T als nonlocal im Bereich von f2 definiere, was bedeutet, dass der erste Code nur im lokalen Bereich von f2 aussieht. Warum passiert das? `

+2

Bitte drücken Sie den Code – ForceBru

+0

[Related.] (Https://stackoverflow.com/questions/44425363/is-it-true-in-python-closure-will-be- stored-if-and-only-if -it-is-country-lex) –

+0

Schauen Sie sich die angenommene Antwort von https://stackoverflow.com/questions/4020419/why-arent-python-nested-functions-called-closures - sehr nette Erklärung dort. – mkiever

Antwort

1

Das Problem hier ist der Kontext für . Standardmäßig verwendet eval die Locals und Globals aus der Umgebung, in der es aufgerufen wird. Wenn wir schreiben:

def f1(): 
    t = 1 

    def f2(x): 
     return eval(x) 
    return f2 

dann in f2 wird t weder in den Globals oder Einheimischen enthalten und wird daher auf die eval-Anweisung nicht zugänglich sein. Python fügt nur t zu den Einheimischen für f2 hinzu, wenn t tatsächlich innerhalb f2 verwendet wird. So etwas überraschend, der folgende Code wird korrekt ausführen:

def f1(): 
    t = 1 

    def f2(x): 
     print(t) 
     return eval(x) 
    return f2 

seit t wird nun innerhalb f2 verwendet. Ein besserer Weg, dies immer zu gewährleisten, arbeitet die folgenden Funktionen ausführen:

def f1(): 
    t = 1 
    eval_globals = globals() 
    eval_locals = locals() 

    def f2(x): 
     return eval(x, eval_globals, eval_locals) 
    return f2 

Dies überschreibt den Kontext für eval, f1 die Globals und Einheimische von im Rahmen der Bereitstellung.

Ein Vorbehalt, da Sie erwähnen, dass Sie ein neuer Programmierer sind: Im Allgemeinen sollten Sie Evaluierungszeitraum vermeiden, es sei denn, Sie haben einen guten Grund, sie zu verwenden. Es gibt bessere Wege, um das zu erreichen, was Sie hier tun, ohne auf eine Bewertung zurückzugreifen.