инструкция exec с / без предварительной компиляции

1

В эти выходные я разрывал на куски Michele Simionato модуль декоратора, который создает декораторы, сохраняющие подпись. В основе всего этого есть динамически сгенерированная функция, которая работает с чем-то подобным...

src = """def function(a,b,c) :\n    return _caller_(a,b,c)\n"""
evaldict = {'_caller_' : _caller_}
code = compile(src, '<string>', 'single')
exec code in evaldict
new_func = evaldict[function]

Я нашел, обманывая этим кодом, что шаг компиляции можно полностью избежать и перейти на один:

exec src in evaldict

Теперь я уверен, что есть веская причина для этого дополнительного шага, но я не смог найти, какая разница между обоими подходами. Производительность?

И так как я спрашиваю, может ли что-то подобное, т.е. определить новую функцию и получить ручку к ней, достичь с помощью eval? Я попытался, но не мог заставить это работать...

Теги:
exec
eval
compilation

2 ответа

2
Лучший ответ

Есть несколько различий, которые я вижу. Во-первых, compile имеет немного лучшую семантику перед ошибками синтаксиса, чем exec. Я подозреваю, что истинная причина в том, что определение compile очень явное в отношении обработки новых символов строки, где exec является немного менее точным.

Мне было любопытно, почему compile и exec, где используются вместо внутренних функций. Я не знал, что compile/exec позволяет вам контролировать, какие глобальные значения доступны. Очень интересно.

  • 0
    Как насчет производительности? Кажется, что компиляция быстрее по какой-то причине?
  • 0
    Я не совсем уверен. Я думаю, что compile будет быстрее, если вы вызываете exec несколько раз с одним и тем же источником. exec вызванный со строкой, скомпилирует строку в байтовый код и затем выполнит ее. Компиляция будет происходить при каждом вызове.
2

compile() позволяет вам управлять созданным объектом кода и его именем и источником, в то время как exec не является настолько гибким. это также стоит сделать так, чтобы другие, читая ваш код, узнали, что они являются отдельными шагами, и подумайте об этом позже, когда им нужно выполнить один и тот же код более одного раза (где compile() один раз, exec несколько раз будет быстрее), и написав свой код для обучения следующего, кто читает, он всегда оказывает достойное влияние на выбор дизайна.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню