Python allows you to dynamically compile things at the module-level. That’s why the compile()
builtin keyword accepts sourcecode and dictionaries of locals and globals, and doesn’t provide a direct way to call a fragment of dynamic (read: textual) sourcecode with arguments (“xyz(arg1, arg2)”). You also can’t directly invoke compiled-code as a generator (where a function that uses “yield” is interpreted as a generator rather than just a function).
However, there’s a loophole, and it’s very elegant and consistent to Python. You simply have to wrap your code in a function definition, and then pull the function from the local scope. You can then call it as desired:
import hashlib import random def _compile(arg_names, code): name = "(lambda compile)" # Needs to start with a letter. id_ = 'a' + str(random.random()) code = "def " + id_ + "(" + ', '.join(arg_names) + "):n" + 'n'.join((' ' + line) for line in code.replace('r', '').split('n')) + 'n' c = compile(code, name, 'exec') locals_ = {} exec(c, globals(), locals_) return locals_[id_] code = """ return a * b * c """ c = _compile(['a', 'b', 'c'], code) print(c(1, 2, 3))