views:

231

answers:

2

These weekend I've been tearing down to pieces Michele Simionato's decorator module, that builds signature-preserving decorators. At the heart of it all there is a dynamically generated function, which works something similar to 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 have found, fooling around with this code, that the compile step can be completely avoided and go for a single:

exec src in evaldict

Now, I'm sure there is a good reason for that additional step, but I haven't been able to find what the difference between both approaches is. Performance?

And since I'm asking, could something similar, i.e. define a new function and get a handle to it, be achieved with eval? I tried, but couldn't get that to work...

+2  A: 

There are a few differences that I see. Firstly, compile has slightly better semantics in the face of syntax errors than exec. I suspect that the real reason is that the definition of compile is very explicit with respect to the handling of new line characters where exec is a little less precise.

I was curious as to why compile and exec where being used in lieu of inner functions. I didn't know that compile/exec lets you control what globals are available. Very interesting.

D.Shawley
+2  A: 

compile() allows you to control the code object created and its name and source, while exec is not so flexible. it is also worth doing so that others, when reading your code, will learn they are separate steps and have this in mind later, when they need to exec the same code more than once (where compile() once, exec multiple times would be faster), and writing your code to educate the next who reads it is always a worthy influence on design choices.

ironfroggy