Is there a way to convert a string to a function in Python while maintaining indentation, newline characters etc.?
For eg., take in "def fn1():\n\tprint("Hello World")"
and convert it to a function:
def fn1():
print("Hello World)
My use case is to allow a user to pass in a function defined by them as a JSON object which is then used in an otherwise static engine.
An example would be:
def run_user_code(fn_str):
fn=convert_to_fn(fn_str)
return fn # or call fn here like fn()
Similar to this question but in Python
CodePudding user response:
You can use the python module ast
import ast
def string_to_function(string):
# parse the string to an ast
tree = ast.parse(string)
# get function name
name = tree.body[0].name # Needs to be changed depending on the input
# compile the ast to executable code
code = compile(tree, '<string>', 'exec')
ns = {}
# exec the code in a namespace
exec(code, ns)
# return the callable function
return ns[name]
s = "def fn1():\n\tprint('Hello World')"
fn = string_to_function(s)
fn()
Output
Hello World
This code only works if the input is a function.
Or you can just call exec()
.
c = "def fn2():\n\tprint('Hello World')"
exec(c)
fn2()
This only works if you already know the function name.
Alwayss be careful what code you execute. In this example the User can put any code inside his function, including imports like os
or sys
, and it will be executed. This can be very dangerous!
CodePudding user response:
It's a bad idea, but you can execute the string as code with
exec('def fn1():\n\tprint("Hello World")')
which defines the function.