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'>
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With