Вопрос

Я пытаюсь выполнить ряд функций с помощью 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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top