2009-05-25 4 views
1

Dieses Wochenende habe ich Michele Simionatos decorator module in Stücke gerissen, die Signatur konservierende Dekorateure baut. Im Herzen von allem gibt es eine dynamisch generierte Funktion, die etwas Ähnliches wie das funktioniert ...Exec Statement mit/ohne vorherige Kompilierung

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] 

ich gefunden habe, Herumalbern mit diesem Code, dass die Kompilierung vollständig vermieden werden kann und geht für ein einziger:

exec src in evaldict 

Nun, ich bin sicher, dass es ein guter Grund für diesen zusätzlichen Schritt ist, aber ich habe nicht in der Lage gewesen zu finden, was der Unterschied zwischen beiden Ansätzen ist. Performance?

Und da ich frage, könnte etwas ähnliches, d. H. Eine neue Funktion definieren und einen Griff dazu bekommen, mit Eval erreicht werden? Ich habe es versucht, aber ich konnte das nicht zur Arbeit bringen ...

Antwort

2

Es gibt ein paar Unterschiede, die ich sehe. Erstens hat compile etwas bessere Semantik angesichts von Syntaxfehlern als exec. Ich vermute, dass der wahre Grund darin besteht, dass die Definition von compile sehr explizit in Bezug auf die Handhabung neuer Zeilenzeichen ist, wobei exec etwas weniger präzise ist.

Ich war neugierig, warum compile und exec wo anstatt der inneren Funktionen verwendet werden. Ich wusste nicht, dass compile/exec Sie steuern können, welche Globals verfügbar sind. Sehr interessant.

+0

Was ist mit der Leistung? Es scheint, dass die Kompilierung aus irgendeinem Grund schneller ist? – Radu

+0

Ich bin mir nicht wirklich sicher. Ich würde annehmen, dass 'compile' schneller wäre, wenn Sie' exec' mehrfach mit derselben Quelle aufrufen. 'exec', das mit einem String aufgerufen wird, kompiliert den String in Byte-Code und führt ihn dann aus. Die Kompilierung würde bei jedem Aufruf stattfinden. –

2

Mit compile() können Sie das erstellte Code-Objekt und dessen Name und Quelle steuern, während exec nicht so flexibel ist. Es lohnt sich auch, dass andere, wenn Sie Ihren Code lesen, lernen, dass es sich um separate Schritte handelt, und beachten Sie dies später, wenn sie denselben Code mehr als einmal ausführen müssen (wo compile() einmal, exec mehrere Male sein würde) schneller) und schreiben Sie Ihren Code, um den nächsten zu unterrichten, der es liest, ist immer ein würdiger Einfluss auf Designentscheidungen.