Exec statement with / without compilation
This weekend I was tearing apart Michele Simionato's decorator module , which creates decorators that preserve the signature. At the heart of it all is a dynamically generated function that works with something like this ...
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]
I found, cheating with this code, that the compilation step can be completely avoided and go to one:
exec src in evaldict
Now I'm sure there is a good reason for this extra step, but I haven't been able to find what the difference is between both approaches. Performance?
And since I am asking if something like this can be, i.e. define a new function and get a handle to it, achieve with eval? I tried but couldn't get this to work ...
a source to share
There are several differences that I can see. First, it compile
has slightly better semantics before syntax errors than exec
. I suspect the real reason is that the definition is compile
very explicit about handling newline characters, where it exec
is slightly less precise.
I was curious why compile
and exec
where are used instead of internal functions. I didn't know that compile
/ exec
allows you to control what global values are available. Very interesting.
a source to share
compile () allows you to manipulate the generated code object and its name and source, while exec is not that flexible. it's also worth doing so that others reading your code will know they are separate steps and think about it later when they need to execute the same code more than once (where compile () is once, exec multiple times will be faster), and by writing your code to educate the next reader, it always makes a decent impact on design choices.
a source to share