Reputation: 338
I'm trying to dynamically generate a function from user input. The user gives a function as a string input, gives the differents parameters, and I want to write a function that will change this string into a usable function. My idea so far was to use the exec
function to create a lambda
function constructed with a string like so : exec("f = lambda {}:{}".format(', '.join(['x'] + parameter_list), function_string))
. This would give, for example, a string like "f = lambda x, a:x+a"
to the exec
function.
This technique works fine if I define the scope of exec
to globals()
, but I'd like my function to be local so that I can do something like this:
def define_function(function_string, parameter_list):
exec("f = lambda {}:{}".format(', '.join(['x'] + parameter_list), function_string))
return f
or like this :
def define_function(function_string, parameter_list):
exec("return lambda {}:{}".format(', '.join(['x'] + parameter_list), function_string))
However, in the first case, it gives an error along the lines of "f is not defined". In the second case, meanwhile, it says that "return can only be used in a function". I understand why the second error occurs, but I wonder why my first try didn't work. Using globals()
makes it work, but I'd rather not use it.
If you have any suggestions for other methods for achieving the same result, I'm interested in those as well.
EDIT
Using eval
also raises an error :
line 9, in define_function
eval("f = lambda {}:{}".format(', '.join(['x'] + parameter_list), function_string))
File "<string>", line 1
f = lambda x, a:x+a
^
SyntaxError: invalid syntax
Upvotes: 1
Views: 149
Reputation: 7559
Solution 1: use eval()
:
def get_func(param_list, result_str):
return eval("lambda {}: {}".format(', '.join(['x'] + param_list), result_str))
Solution 2: if you really want to use exec()
, do something like this:
def get_func(param_list, result_str):
exec("f = lambda {}: {}".format(', '.join(['x'] + param_list), result_str))
return locals()['f']
Some good info on the differences between exec
and eval
here: What's the difference between eval, exec, and compile?
I can see what you're trying to do in your question, by the way, and it's worth noting that the documentation pages for exec()
and locals()
both explicitly warn that this won't work. Ditto, if you type help(locals)
into the interactive interpreter, you get this message:
Help on built-in function locals in module builtins:
locals()
Return a dictionary containing the current scope's local variables.
NOTE: Whether or not updates to this dictionary will affect name lookups in
the local scope and vice-versa is *implementation dependent* and not
covered by any backwards compatibility guarantees.
Upvotes: 1