Die Python-C-API-Funktion PyEval_EvalCode
lässt Sie kompilierten Python-Code ausführen. Ich möchte einen Block von Python-Code so ausführen, als ob er im Rahmen einer Funktion ausgeführt würde, so dass er sein eigenes Wörterbuch lokaler Variablen hat, die den globalen Zustand nicht beeinflussen.C Python: Ausführen von Python-Code in einem Kontext
Das scheint einfach genug zu tun, da PyEval_EvalCode
können Sie einen globalen und lokalen Wörterbuch bieten:
PyObject* PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)
Das Problem, das ich in laufen hat damit zu tun, wie Python Variablennamen sucht. Betrachten Sie den folgenden Code ein, dass ich mit PyEval_EvalCode
ausführen:
myvar = 300
def func():
return myvar
func()
Dieser einfache Code wirft tatsächlich einen Fehler, weil Python ist nicht in der Lage die Variable myvar
aus func
zu finden. Obwohl sich myvar
im äußeren Wörterbuch im lokalen Wörterbuch befindet, kopiert Python es nicht in das lokale Wörterbuch im inneren Bereich. Der Grund dafür ist wie folgt:
Immer wenn Python nach einem Variablennamen sucht, überprüft es zuerst locals
, dann überprüft es globals
, und schließlich prüft es builtins
. Bei Modulbereich, locals
und globals
sind die gleichen Wörterbuchobjekt. So wird die Anweisung x = 5
im Modulbereich x
im locals
Wörterbuch platziert, das auch das globals
Wörterbuch ist. Nun wird eine im Modulbereich definierte Funktion, die nach x
suchen muss, x
nicht innerhalb des Funktionsbereichs locals
finden, da Python Modul-Scope-Locals nicht in Funktionsbereichs-Locals kopiert. Aber das ist normalerweise kein Problem, denn es kann x
in globals
finden.
x = 5
def foo():
print(x) # This works because 'x' in globals() == True
Es ist nur mit verschachtelten Funktionen, dass Python scheint äußeren Umfang Einheimischen in inner Umfang Einheimischen zu kopieren. (Es scheint auch so faul zu tun, nur, wenn sie innerhalb des inneren Umfangs benötigt werden.)
def foo():
x = 5
def bar():
print(x) # Now 'x' in locals() == True
bar()
So das Ergebnis des Ganzen ist, dass, wenn der Code bei Modul Rahmen Ausführung, müssen Sie Stellen Sie sicher, dass Ihr globales Wörterbuch und Ihr lokales Wörterbuch das SAME-Objekt sind, andernfalls können Module-Scope-Funktionen nicht auf Module-Scope-Variablen zugreifen.
Aber in meinem Fall möchte ich nicht, dass das globale Wörterbuch und das lokale Wörterbuch gleich sind. Also muss ich dem Python-Interpreter sagen, dass ich Code im Funktionsumfang ausführe. Gibt es einen Weg, dies zu tun? Ich schaute auf die PyCompileFlags
sowie die zusätzlichen Argumente zu PyEval_EvalCodeEx
und kann keine Möglichkeit finden, dies zu tun.
@ Channel72 siehe oben. – ecatmur