2016-04-17 33 views
1

In Python 2 (nicht sicher über 3), das lokale Wörterbuch wird nur aktualisiert, wenn Sie tatsächlich Locals() aufrufen. So z.B.Wie kann ich die Aktualisierung des lokalen Python-Wörterbuchs() eines anderen Stapelrahmens erzwingen?

l=locals() 
x=2 
l['x'] 

schlägt fehl, da l nicht die Taste "x" in ihm haben, aber

l=locals() 
x=2 
locals() 
l['x'] 

kehrt 2.

ich nach einer Möglichkeit, ein Update von der Kraft Einheimische Wörterbuch, aber der Trick ist, dass ich in einem anderen Stapelrahmen bin. So z.B. Ich bin auf der Suche

l=locals() 
x=2 
force_update() 
l['x'] 

zu tun und ich brauche die force_update() Funktion zu schreiben. Ich weiß, dass von der Funktion kann ich den Elternrahmen über inspect.currentframe().f_back, und sogar die Eltern (nicht aktualisiert) Einheimischen über inspect.currentframe().f_back.f_locals, aber wie kann ich ein Update erzwingen?

Wenn das scheint gewunden, mein Hauptziel ist es, eine Funktion, die Kurzform für "{some} string".format(**dict(globals(),**locals())) zu schreiben, so muss ich nicht jedes Mal, und kann stattdessen fmt("{some} string") tun. Ich stoße dabei auf das obige Problem.

Bearbeiten: Mit Martjin Antwort unten, unten ist im Wesentlichen die Lösung, die ich suchte. Man könnte mit genau umgehen, wie sie den Stack Frame des Angerufenen bekommen, hier mache ich es über partial.

from functools import partial 
from inspect import currentframe 

fmt = partial(lambda s,f: s.format(**dict(globals(),**f.f_locals)),f=currentframe()) 
x=2 
print fmt("{x}") #prints "2" 
+0

In Ihrem Editor könnten Sie eine Verknüpfung, ein Snippet oder was auch immer der Editor es nennt, um '.format (** dict (globals(), ** localhosts()))' 'zu definieren. Viele Redakteure unterstützen so etwas. –

+0

Warum verwenden Sie '" {einige} string ".format (** dict (globals(), ** localhosts())) so oft in Ihrem Code? Benötigt Ihre Format-Zeichenfolge wirklich Zugriff auf alle Variablen im lokalen und globalen Namespace? – emeraldemon

+0

Wenn Sie den Eltern-Frame erhalten können (siehe auch 'sys._getframe (1)'), warum brauchen Sie dann 'globals()' und 'localhosts()'? – cdarke

Antwort

1

Einfach f_locals auf einem Frame-Objekt Zugriff auf löst die Kopie zu verwenden, da inspect.currentframe().f_back.f_localsgenug ist.

Siehe frame_getlocals() function in der frameobject.c Umsetzung:

static PyObject * 
frame_getlocals(PyFrameObject *f, void *closure) 
{ 
    PyFrame_FastToLocals(f); 
    Py_INCREF(f->f_locals); 
    return f->f_locals; 
} 

PyFrame_FastToLocals die Funktion zum Kopieren der Daten aus dem interal Array Tracking Einheimischen Werte in ein Wörterbuch verwendet wird. frame_getlocals wird verwendet, um den Deskriptor frame.f_locals (eine Eigenschaft) zu implementieren; siehe frame_getsetlist definition.

Die PyFrame_FastToLocalsWithError Funktion oben verwendete genau was locals() das gleiche Wörterbuch zu produzieren verwendet (durch wrapping die PyEval_GetLocals function).

+0

Aha! Vielen Dank. Ich habe 'currentframe(). F_locals' gefunden, merke aber nicht, dass es das Update, nach dem ich gesucht habe, genau erzwingt. – marius

+0

Ja - Vorsicht, das Gegenteil passiert nicht - es gibt keine Möglichkeit, die schnellen Variablen durch Ändern der Werte in den Locals zu aktualisieren. – jsbueno

+0

funktioniert das für Python 3 oder höher? –