Python: dynamically create function at runtime
PythonFunctionRuntimePython Problem Overview
How to dynamically create a function in Python?
I saw a few answers here but I couldn't find one which would describe the most general case.
Consider:
def a(x):
return x + 1
How to create such function on-the-fly? Do I have to compile('...', 'name', 'exec')
it? But what then? Creating a dummy function and replacing its code object for then one from the compile step?
Or should I use types.FunctionType
? How?
I would like to customize everything: number of argument, their content, code in function body, the result, ...
Python Solutions
Solution 1 - Python
Use exec
:
>>> exec("""def a(x):
... return x+1""")
>>> a(2)
3
Solution 2 - Python
Did you see this, its an example which tells you how to use types.FunctionType
Example:
import types
def create_function(name, args):
def y(): pass
y_code = types.CodeType(args,
y.func_code.co_nlocals,
y.func_code.co_stacksize,
y.func_code.co_flags,
y.func_code.co_code,
y.func_code.co_consts,
y.func_code.co_names,
y.func_code.co_varnames,
y.func_code.co_filename,
name,
y.func_code.co_firstlineno,
y.func_code.co_lnotab)
return types.FunctionType(y_code, y.func_globals, name)
myfunc = create_function('myfunc', 3)
print repr(myfunc)
print myfunc.func_name
print myfunc.func_code.co_argcount
myfunc(1,2,3,4)
# TypeError: myfunc() takes exactly 3 arguments (4 given)
Solution 3 - Python
If you need to dynamically create a function from a certain template try this piece:
def create_a_function(*args, **kwargs):
def function_template(*args, **kwargs):
pass
return function_template
my_new_function = create_a_function()
Within function create_a_function() you can control, which template to chose. The inner function function_template serves as template. The return value of the creator function is a function. After assignment you use my_new_function as a regular function.
Typically, this pattern is used for function decorators, but might by handy here, too.
Solution 4 - Python
You can use lambda for this.
a = lambda x: x + 1
>>> a(2)
3
Solution 5 - Python
What about this approach?
In this example I'm parametrizing first order functions on one variable (x -> ax+b) in one class:
class Fun:
def __init__(self, a,b):
self.a, self.b = a,b
def f(self, x):
return (x*self.a + self.b)
u = Fun(2,3).f
Here u
will be the function x->2x+3.
Solution 6 - Python
You can do at this manner:
new_func='def next_element(x):\n return x+1'
the_code=compile(new_func,'test','exec')
exec(the_code)
next_element(1)
It's similar to the previous exec solution.
Solution 7 - Python
simpler than Berci's answer
def get_fn(a, b): # factory function
def fn(): # result function
print(a, b)
return fn
fn = get_fn(1, 2)
fn()
this is useful to turn variables into constants ("template variables for dynamic functions")