繁体   English   中英

function的code object使用Python exec如何获取返回值?

[英]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!

来自exec 上Python 3 文档

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM