2009-05-25 11 views
1

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

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? Я пробовал, но не мог заставить это работать ...

ответ

2

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

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

+0

Как насчет производительности? Кажется, что компиляция быстрее по какой-то причине? – Radu

+0

Я не уверен. Я бы предположил, что 'compile' будет быстрее, если вы вызываете' exec' несколько раз с тем же источником. 'exec', вызываемый со строкой, скомпилирует строку в байтовый код и затем выполнит ее. Компиляция будет происходить при каждом вызове. –

2

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

 Смежные вопросы

  • Нет связанных вопросов^_^