C Python: запуск кода Python в контексте

API-функция Python CPyEval_EvalCode позвольте вам выполнить скомпилированный код Python. Я хочу выполнить блок кода Pythonas if it were executing within the scope of a function, так что он имеет свой собственный словарь локальных переменных, которые не влияют на глобальное состояние.

Это кажется достаточно простым, посколькуPyEval_EvalCode позволяет вам предоставить глобальный и локальный словарь:

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

Проблема, с которой я сталкиваюсь, связана с тем, как Python ищет имена переменных. Рассмотрим следующий код, который я выполняю сPyEval_EvalCode:

myvar = 300
def func():
    return myvar

func()

Этот простой код на самом деле вызывает ошибку, потому что Python не может найти переменнуюmyvar изнутриfunc, Даже еслиmyvar находится в локальном словаре во внешней области видимости, Python не копирует его в локальный словарь во внутренней области видимости. Причина этого заключается в следующем:

Всякий раз, когда Python ищет имя переменной, сначала он проверяетlocalsзатем проверяетglobalsи, наконец, это проверяетbuiltins, Вmodule scope, locals а такжеglobals ОДИНАКОВЫЙ объект словаря. Итак, утверждениеx = 5 в объеме модуля разместитx вlocals словарь, который также являетсяglobals толковый словарь. Теперь функция, определенная в области видимости модуля, которая должна искатьx не найдуx в пределах объема функцииlocalsпотому что Python не копирует локальные области видимости модуля в локальные области видимости функции. Но это обычно не проблема, потому что он может найтиx вglobals.

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

Это только сnested функции, которые Python, кажется, копирует локальные локальные области видимости в локальные области видимости. (Это также кажется ленивым, только если они необходимы во внутренней области.)

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


Таким образом, результатом всего этого является то, что при выполнении кода наmodule scopeВы ДОЛЖНЫ убедиться, что ваш глобальный словарь и локальный словарь являются ОДНЫМ объектом, в противном случае функции области модуля не смогут получить доступ к переменным области модуля.

Но в моем случае я не хочу, чтобы глобальный словарь и локальный словарь были одинаковыми. Поэтому мне нужен какой-то способ сообщить интерпретатору Python, что я выполняю код в области действия функции. Есть ли способ сделать это? Я посмотрел наPyCompileFlags а также дополнительные аргументыPyEval_EvalCodeEx и не могу найти никакого способа сделать это.

Ответы на вопрос(1)

Ваш ответ на вопрос