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…
There are a few differences that I see. Firstly,
compilehas slightly better semantics in the face of syntax errors thanexec. I suspect that the real reason is that the definition ofcompileis very explicit with respect to the handling of new line characters whereexecis a little less precise.I was curious as to why
compileandexecwhere being used in lieu of inner functions. I didn’t know thatcompile/execlets you control what globals are available. Very interesting.