C Python: Ejecutar código Python dentro de un contexto

La función API de Python CPyEval_EvalCode vamos a ejecutar código compilado de Python. Quiero ejecutar un bloque de código PythonComo si se estuviera ejecutando dentro del alcance de una función., para que tenga su propio diccionario de variables locales que no afectan el estado global.

Esto parece bastante fácil de hacer, ya quePyEval_EvalCode le permite proporcionar un diccionario global y local:

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

El problema con el que me encuentro tiene que ver con cómo Python busca nombres de variables. Considere el siguiente código, que ejecuto conPyEval_EvalCode:

myvar = 300
def func():
    return myvar

func()

Este código simple genera un error, ya que Python no puede encontrar la variablemyvar desde dentrofunc. Aunquemyvar está en el diccionario local en el ámbito externo, Python no lo copia en el diccionario local en el ámbito interno. La razón de esto es la siguiente:

Cada vez que Python busca un nombre de variable, primero verificalocalsluego compruebaglobals, y finalmente se comprueba.builtins. Aalcance del módulo, locals yglobals son el mismo objeto de diccionario. Así que la declaraciónx = 5 en el alcance del módulo colocaráx en ellocals diccionario, que es también elglobals diccionario. Ahora, una función definida en el alcance del módulo que necesita buscarx no encontrarax dentro del alcance de la funciónlocals, porque Python no copia los locales de alcance de módulo en los locales de alcance de función. Pero esto normalmente no es un problema, porque puede encontrarx englobals.

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

Es solo conanidado funciones, que Python parece copiar los locales de ámbito externo en los locales de ámbito interno. (También parece que lo hace perezosamente, solo si son necesarios dentro del ámbito interno).

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


Entonces el resultado de todo esto es que, al ejecutar código enalcance del módulo, TIENE QUE asegurarse de que su diccionario global y su diccionario local sean el MISMO objeto, de lo contrario, las funciones de alcance de módulo no podrán acceder a las variables de alcance de módulo.

Pero en mi caso, NO QUIERO que el diccionario global y el diccionario local sean iguales. Así que necesito alguna forma de decirle al intérprete de Python que estoy ejecutando código en el ámbito de la función. Hay alguna manera de hacer esto? Miré elPyCompileFlags así como los argumentos adicionales aPyEval_EvalCodeEx y no puedo encontrar ninguna manera de hacer esto.

Respuestas a la pregunta(1)

Su respuesta a la pregunta