How can i get python function object from a string
Question:
I have python functions in string format and I want to get the python objects of these functions in the scope of the program. I have tried exec()
, eval()
and ast.literal_eval()
but none of these return a function object.
For example:
s = "def add(args):n try:n return sum([int(x) for x in args])n except Exception as e:n return 'error'n
this is a simple function in string to add elements of a list. I am looking for a module of utility which can return the object of the function add
function_obj = some_function(s)
print 'type:', type(function_obj)
type: <type 'function'>
Answers:
In Python 2, you can give a globals dictionary to exec
:
globalsdict = {}
exec s in globalsdict
And then globalsdict[‘add’] will be your function object. Globalsdict will also contain all the builtins.
a =
'''def fun():n
print 'result'
'''
exec(a)
fun()
One way (there might be better ones – e.g. [Python.Docs]: Built-in functions – compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1) as pointed out by @Abdul-Niyas-P-M’s answer) would be to:
-
Use [Python 3.Docs]: Built-in Functions – exec(object, globals=None, locals=None, /, *, closure=None), to execute the code, but in a restricted scope
-
Wrap it in a function
>>> s = "def add(args):n try:n return sum([int(x) for x in args])n except Exception as e:n return 'error'"
>>>
>>> def create_func_obj(func_code_str):
... g = dict()
... l = dict()
... exec(func_code_str, g, l)
... if l:
... return list(l.values())[0]
...
>>>
>>> func = create_func_obj(s)
>>>
>>> func
<function add at 0x000002952F0DEC80>
>>> func([1, 2, 3])
6
>>>
>>> add # The function wasn't added in the global namespace (as an exec sideeffect)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'add' is not defined
If the code string contains other things besides the definition of one function, the results will not be the expected ones.
First compile the function(as string) into code object ie,
code_obj = compile(s, '<string>', 'exec')
and then use types.FunctionType
to create new function type from code object.
>>> import types
>>> new_func_type = types.FunctionType(code_obj.co_consts[0], globals())
>>> print(type(new_func_type))
<class 'function'>
>>> new_func_type([*range(10)])
45
I have python functions in string format and I want to get the python objects of these functions in the scope of the program. I have tried exec()
, eval()
and ast.literal_eval()
but none of these return a function object.
For example:
s = "def add(args):n try:n return sum([int(x) for x in args])n except Exception as e:n return 'error'n
this is a simple function in string to add elements of a list. I am looking for a module of utility which can return the object of the function add
function_obj = some_function(s)
print 'type:', type(function_obj)
type: <type 'function'>
In Python 2, you can give a globals dictionary to exec
:
globalsdict = {}
exec s in globalsdict
And then globalsdict[‘add’] will be your function object. Globalsdict will also contain all the builtins.
a =
'''def fun():n
print 'result'
'''
exec(a)
fun()
One way (there might be better ones – e.g. [Python.Docs]: Built-in functions – compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1) as pointed out by @Abdul-Niyas-P-M’s answer) would be to:
-
Use [Python 3.Docs]: Built-in Functions – exec(object, globals=None, locals=None, /, *, closure=None), to execute the code, but in a restricted scope
-
Wrap it in a function
>>> s = "def add(args):n try:n return sum([int(x) for x in args])n except Exception as e:n return 'error'" >>> >>> def create_func_obj(func_code_str): ... g = dict() ... l = dict() ... exec(func_code_str, g, l) ... if l: ... return list(l.values())[0] ... >>> >>> func = create_func_obj(s) >>> >>> func <function add at 0x000002952F0DEC80> >>> func([1, 2, 3]) 6 >>> >>> add # The function wasn't added in the global namespace (as an exec sideeffect) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'add' is not defined
If the code string contains other things besides the definition of one function, the results will not be the expected ones.
First compile the function(as string) into code object ie,
code_obj = compile(s, '<string>', 'exec')
and then use types.FunctionType
to create new function type from code object.
>>> import types
>>> new_func_type = types.FunctionType(code_obj.co_consts[0], globals())
>>> print(type(new_func_type))
<class 'function'>
>>> new_func_type([*range(10)])
45