C Python: Ausführen von Python-Code in einem Kontext

Die Python C-API-FunktionPyEval_EvalCode Lassen Sie uns kompilierten Python-Code ausführen. Ich möchte einen Block Python-Code ausführenals würde es im Rahmen einer Funktion ausgeführt, so dass es ein eigenes Wörterbuch lokaler Variablen hat, die den globalen Zustand nicht beeinflussen.

Dies scheint einfach genug zu sein, daPyEval_EvalCode Mit dieser Option können Sie ein globales und ein lokales Wörterbuch bereitstellen:

PyObject* PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)

Das Problem, auf das ich stoße, hat damit zu tun, wie Python Variablennamen sucht. Betrachten Sie den folgenden Code, mit dem ich ausführePyEval_EvalCode:

myvar = 300
def func():
    return myvar

func()

Dieser einfache Code löst tatsächlich einen Fehler aus, da Python die Variable nicht finden kannmyvar von innenfunc. Obwohlmyvar befindet sich im lokalen Wörterbuch im äußeren Bereich, Python kopiert es nicht in das lokale Wörterbuch im inneren Bereich. Der Grund dafür ist wie folgt:

Wann immer Python einen Variablennamen nachschlägt, prüft es zuerstlocals, dann prüft esglobalsund schließlich prüft esbuiltins. BeimModulumfang, locals undglobals sind das gleiche Dictionary-Objekt. Also die Aussagex = 5 am Modulumfang wird platziertx in derlocals Wörterbuch, das auch das istglobals Wörterbuch. Nun wird eine Funktion im Modulbereich definiert, die nachgeschlagen werden mussx werde nicht findenx innerhalb des Funktionsumfangslocals, weil Python keine Module-Scope-Locals in Function-Scope-Locals kopiert. Aber das ist normalerweise kein Problem, weil es finden kannx imglobals.

x = 5
def foo():
   print(x) # This works because 'x' in globals() == True

Es geht nur mitverschachtelt funktioniert, dass Python anscheinend Outer-Scope-Locals in Inner-Scope-Locals kopiert. (Es scheint auch so träge zu sein, nur wenn sie im inneren Bereich benötigt werden.)

def foo():
   x = 5
   def bar():
      print(x) # Now 'x' in locals() == True
   bar()


Das Ergebnis all dessen ist, dass beim Ausführen von Code umModulumfangMÜSSEN Sie sicherstellen, dass Ihr globales und lokales Wörterbuch das gleiche Objekt sind, da sonst Modulbereichsfunktionen nicht auf Modulbereichsvariablen zugreifen können.

In meinem Fall möchte ich jedoch nicht, dass das globale und das lokale Wörterbuch gleich sind. Ich muss dem Python-Interpreter also mitteilen, dass ich Code im Funktionsumfang ausführe. Gibt es eine Möglichkeit, dies zu tun? Ich schaute auf diePyCompileFlags sowie die zusätzlichen Argumente zuPyEval_EvalCodeEx und kann keinen Weg finden, dies zu tun.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage