True dynamic and anonymous functions possible in Python?

python

Solution

There is `types.FunctionType` which you can use to dynamically create a function e.g.

def test_func(): print 'wow' 
dynf = types.FunctionType(test_func.func_code, {})
dynf()

Output:

wow

You might object that this is not dynamic because I am using code from another function, but that was just an example there is a way to generate code from python strings e.g.

dynf = types.FunctionType(compile('print "really WoW"', 'dyn.py', 'exec'), {})
dynf()

Output:

really WoW

Now that is dynamic!

OP is worried about the dynamic nature of such function so here is another example

dynf = types.FunctionType(compile('test_func():\ntest_func()', 'dyn.py', 'exec'), globals())
dynf()

Output:

wow
wow

Note: Creating Function object like this seems to have limitations e.g. it is not easy to pass arguments, because to pass arguments we need to pass correct co_argcount, co_varnames and other 12 variables to `types.CodeType`, which theoretically can be done but will be error prone, an easier way is to import string as a module and you have a full fledged function e.g.

import types
import sys,imp

code = """def f(a,b,c):
    print a+b+c, "really WoW"
"""
module = imp.new_module('myfunctions')
exec code in module.__dict__
module.f('W', 'o', 'W')

Output:

WoW really WoW

Problem

Just as a dynamic class can be created using type(name, base-classes, namespace-dict), can a dynamic function be created? I've tried doing something along the lines of: ``` >>> f = type("f", (function,), {}) NameError: name 'function' is not defined ``` Ok, so I'll be clever, but: ``` >>> def fn(): ... pass ... >>> type(fn) <type 'function'> >>> f = type("f", (type(fn),), {}) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: type 'function' is not an acceptable base type ``` Does Python specifically prevent the creation of dynamic functions in the same way it allows dynamic classes? Edit: Note, I'd disallow any use of exec.. Since my question is does the Python language itself permit this. Thanks in advance.

Original source

Related problems