Вопрос
Я пытаюсь выполнить ряд функций с помощью eval(), и мне нужно создать какую-то среду для их запуска.В документации сказано, что вы можете передавать глобальные переменные в качестве второго параметра в eval().
Но, похоже, в моем случае это не работает.Вот упрощенный пример (я попробовал два подхода: объявить переменную глобальной и использовать globals(), и оба не работают):
Файл скрипт.py:
import test
global test_variable
test_variable = 'test_value'
g = globals()
g['test_variable'] = 'test_value'
eval('test.my_func()', g)
Файл test.py:
def my_func():
global test_variable
print repr(test_variable)
И я получаю:
ИмяОшибка:глобальное имя «test_variable» не определено.
Что мне сделать, чтобы пройти это test_variable
в my_func()
?Предполагая, что я не могу передать его как параметр.
Решение
test_variable должен быть глобальным в test.py.Вы получаете ошибку имени, потому что пытаетесь объявить глобальную переменную, которая еще не существует.
Итак, ваш файл my_test.py должен выглядеть следующим образом:
test_variable = None
def my_func():
print test_variable
И запустим это из командной строки:
>>> import my_test
>>> eval('my_test.my_func()')
None
>>> my_test.test_variable = 'hello'
>>> my_test.test_variable
'hello'
>>> eval('my_test.my_func()')
hello
Обычно использование eval() и глобальных переменных является плохим тоном, поэтому убедитесь, что вы знаете, что делаете.
Другие советы
Поправьте меня, эксперты по Python, если я ошибаюсь.Я также изучаю Python.Ниже приводится мое нынешнее понимание того, почему NameError
было выбрано исключение.
В Python вы не можете создать переменную, к которой можно будет обращаться из всех модулей, без указания имени модуля (т. е.для доступа к глобальной переменной test
в модуле mod1
вам нужно использовать mod1.test
когда ты в модуле mod2
).Область действия глобальной переменной в значительной степени ограничена самим модулем.
Таким образом, когда у вас есть следующие test.py
:
def my_func():
global test_variable
print repr(test_variable)
А test_variable
здесь относится к test.test_variable
(т.е. test_variable
в test
пространство имен модуля).
Итак, установка test_variable
в script.py
поместит переменную в __main__
пространство имен (__main__
потому что это модуль/скрипт верхнего уровня, который вы предоставили интерпретатору Python для выполнения).Таким образом, это test_variable
будет в другом пространстве имен, а не в test
пространство имен модуля, где оно должно быть.Следовательно, Python генерирует NameError
потому что он не может найти переменную после поиска test
глобальное пространство имен модуля и встроенное пространство имен (пространство имен локальных функций пропускается из-за global
заявление).
Поэтому для eval
для работы нужно настроить test_variable
в test
пространство имен модуля в script.py
:
import test
test.test_variable = 'test_value'
eval('test.my_func()')
Более подробную информацию об области действия и пространствах имен Python см.: http://docs.python.org/tutorial/classes.html#python-scopes-and-name-spaces