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'>
Asked By: vasu gaur

||

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.

Answered By: RemcoGerlich
a = 
'''def fun():n
    print 'result'
'''
exec(a)

fun()
Answered By: BramAppel

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:

>>> 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.

Answered By: CristiFati

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
Answered By: Abdul Niyas P M
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.