exec
ничего не возвращает. Вместо этого вы можете назначить ему что-то вроде этого:
def f():
a = 1
v = 2
return 1
import inspect
st = inspect.getsource(f) + '\nret=f()'
exec(st)
print(ret) # prints 1
Вот еще один вариант, но он очень уродливый ...
In [65]: def f():
...: a = 1
...: v = 2
...: return 1
...:
In [66]: def my_exec(func):
...: try:
...: code = inspect.getsource(func)
...: func_name = func.__name__
...: exec('global ret\n{}\nret={}()'.format(code, func_name))
...: global ret
...: return ret
...: except IOError:
...: return None
...:
In [67]: my_exec(f)
Out[67]: 1
Это создаст глобальный ret
, определите функцию и затем запустите функцию, назначив возврат на ret
. Наконец, возвращается то, что ret
содержит. Определив свою собственную функцию exec
, вы получите больший контроль над тем, что происходит до / после.