Подтвердить что ты не робот

Почему для операторов импорта Python должен использоваться "exec" (а не "eval" )?

Я пытаюсь запустить фрагмент Python из Java, используя Jython. Если я использую инструкцию exec для импорта, все работает.

PythonInterpreter pi = new PythonInterpreter();
pi.exec("import re");
PythonObject o = pi.eval("re.match('abc', 'abc123')"); // returns a MatchObject
o = pi.eval("re.match('abc', 'def123')"); // returns Py.None

Если, однако, я пытаюсь совместить две линии, все ад разрывается. Это:

PythonInterpreter pi = new PythonInterpreter();
pi.eval("import re"); // exception!
PythonObject o = pi.eval("re.match('abc', 'abc123')"); // never gets here
o = pi.eval("re.match('abc', 'def123')"); // ....

... выдает исключение "no viable alternative at input 'import'", ('<string>',1,0,'import re\n').

Это важно, потому что в идеале я хотел бы иметь возможность оценивать целую script как одну строку без необходимости разбить импорт на отдельную часть. Я делаю что-то неправильно? Есть ли другой способ сказать Jython "взять весь этот блок script, включая импорт, и запустить его, а затем вернуть результат"? Это должно быть во время выполнения - предварительная компиляция файлов Python в файлы .class не является вариантом.

4b9b3361

Ответ 1

Проблема заключается в том, что eval оценивает выражения и возвращает некоторый результат, а exec выполняет инструкции в некотором контексте. import - это инструкция, а функция re.match() - выражение.

Ответ 2

Попробуйте это,

eval("__import__('re').match('abc', 'abc123')")

Ответ 3

Вот что вы подразумеваете под результатом?

Я предполагаю, что это некоторая вычисленная величина вашего script. Согласно документации "exec" код работает в текущей области. Следовательно, вы должны иметь доступ к значениям любых новых символов, которые вы создали внутри оператора exec.

a = 20
b = 10
exec("c = a + b")
print c

Приведенный выше код должен напечатать 30.