[英]How do I get the return value when using Python exec on the code object of a function?
出于测试目的,我想直接执行在另一个 function 内部定义的 function。
我可以通过父 function 的代码(func_code)获取子 function 的代码 object,但是当我执行它时,我没有返回值。
有没有办法从执行代码中获取返回值?
是的,您需要在exec
语句中进行赋值:
>>> def foo():
... return 5
...
>>> exec("a = foo()")
>>> a
5
这可能与您的情况无关,因为它用于受控测试,但在使用exec
和用户定义的输入时要小心。
几年后,但以下片段帮助了我:
the_code = '''
a = 1
b = 2
return_me = a + b
'''
loc = {}
exec(the_code, globals(), loc)
return_workaround = loc['return_me']
print(return_workaround) # 3
exec()
本身不返回任何内容,但您可以传递一个dict
,其中在执行后存储了所有局部变量。 通过访问它,您可以获得类似回报的东西。
我希望它可以帮助某人。
虽然这是人类见过的最丑陋的野兽,但您可以通过在 exec 调用中使用全局变量来做到这一点:
def my_exec(code):
exec('global i; i = %s' % code)
global i
return i
这是滥用全局变量来跨越边界获取数据。
>>> my_exec('1 + 2')
3
毋庸置疑,您永远不应该允许任何用户输入用于此功能的输入,因为它会带来极大的安全风险。
这样的事情可以工作:
def outer():
def inner(i):
return i + 10
for f in outer.func_code.co_consts:
if getattr(f, 'co_name', None) == 'inner':
inner = type(outer)(f, globals())
# can also use `types` module for readability:
# inner = types.FunctionType(f, globals())
print inner(42) # 52
这个想法是从内部函数中提取代码对象并基于它创建一个新函数。
当内部函数可以包含自由变量时,需要额外的工作。 您还必须提取它们并传递给最后一个参数( closure
)中的函数构造函数。
这是一种从 exec 代码返回值的方法:
def exec_and_return(expression):
exec(f"""locals()['temp'] = {expression}""")
return locals()['temp']
我建议你举一个你试图解决的问题的例子。 因为我只会把它作为最后的手段。
这不会得到每个说的返回值,但是在调用exec
以检索代码中定义的任何变量时,您可以提供一个空字典。
# Python 3
ex_locals = {}
exec("a = 'Hello world!'", None, ex_locals)
print(ex_locals['a'])
# Output: Hello world!
默认 locals 的行为如下面的函数
locals()
所述:不应尝试修改默认 locals 字典。 如果您需要在函数exec()
返回后查看代码对局部变量的影响,请传递一个显式局部变量字典。
有关更多信息,请参阅exec 如何与本地人一起工作?
这是一个带有简单代码的解决方案:
# -*- coding: utf-8 -*-
import math
x = [0]
exec("x[0] = 3*2")
print(x[0]) # 6
从 Python 3.7 开始,字典是有序的。 因此,您不再需要就名称达成一致,您只需说“最后创建的项目”:
>>> d = {}
>>> exec("def addone(i): return i + 1", d, d)
>>> list(d)
['__builtins__', 'addone']
>>> thefunction = d[list(d)[-1]]
>>> thefunction
<function addone at 0x7fd03123fe50>
使用eval()
而不是exec()
,它返回结果
如果我们需要一个位于另一个目录中的文件中的函数,例如
我们需要在文件my_py_file.py期函数
位于/home/.../another_directory
我们可以使用以下代码:
def cl_import_function(a_func,py_file,in_Dir):
... 导入系统
... sys.path.insert(0, in_Dir)
... ax='from %s import %s'%(py_file,a_func)
... loc={}
... exec(ax, globals(), loc)
... getFx = loc[afunc]
...返回getFx
test = cl_import_function('function1',r'my_py_file',r'/home/.../another_directory/')
测试()
(新手的简单方法...)
program = 'a = 5\nb=10\nprint("Sum =", a + b)'
program = exec(program)
print(program)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.