Eval () и глобальные () Python - PullRequest
       17

Eval () и глобальные () Python

8 голосов
/ 08 апреля 2009

Я пытаюсь выполнить ряд функций, используя eval (), и мне нужно создать какую-то среду для их запуска. В документации сказано, что вы можете передавать глобальные переменные в качестве второго параметра в eval ().

Но, похоже, не работает в моем случае. Вот упрощенный пример (я попробовал два подхода, объявляя переменную global и используя globals (), и оба не работают):

Файл script.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)

И я получаю:

NameError: глобальное имя 'test_variable' не определено.

Что я должен сделать, чтобы передать это test_variable в my_func()? Предполагая, что я не могу передать его в качестве параметра.

Ответы [ 2 ]

10 голосов
/ 08 апреля 2009

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 () и глобальные переменные неправильно, поэтому убедитесь, что вы знаете, что делаете.

4 голосов
/ 08 апреля 2009

Пожалуйста, поправьте меня экспертами 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

...