Когда вы вызываете функцию в Python, глобальные переменные, которые она видит, всегда являются глобальными переменными модуля, в котором она была определена. (Если это не так, функция может не работать - на самом деле нужно некоторые глобальные значения, и вы не обязательно знаете, что это такое.) Указание словаря глобалов с exec
или eval()
влияет только на глобалы, код которых exec
'd или eval()
' г видит.
Если вы хотите, чтобы функция видела другие глобальные переменные, вам действительно нужно включить определение функции в строку, которую вы передаете exec
или eval()
. Когда вы это делаете, «модуль» функции - это строка, из которой она была скомпилирована, со своими собственными глобальными переменными (т. Е. Теми, которые вы указали).
Вы можете обойти это, создав новую функцию с тем же объектом кода, что и тот, который вы вызываете, но с другим атрибутом func_globals
, который указывает на ваш глобальный запрос, но это довольно продвинутая хакерская программа и, вероятно, не стоит , Тем не менее, вот как вы это сделаете:
# create a sandbox globals dict
sandbox = {}
# create a new version of test() that uses the sandbox for its globals
newtest = type(test)(test.func_code, sandbox, test.func_name, test.func_defaults,
test.func_closure)
# add the sandboxed version of test() to the sandbox
sandbox["test"] = newtest