Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在函数的代码对象上使用Python exec时,如何获取返回值?_Python_Function_Return_Exec - Fatal编程技术网

在函数的代码对象上使用Python exec时,如何获取返回值?

在函数的代码对象上使用Python exec时,如何获取返回值?,python,function,return,exec,Python,Function,Return,Exec,出于测试目的,我希望直接执行在另一个函数中定义的函数 我可以通过父函数的代码(func_code)访问子函数的code对象,但是当我执行它时,没有返回值 有没有办法从执行代码中获取返回值?是的,您需要在exec语句中进行赋值: >>> def foo(): ... return 5 ... >>> exec("a = foo()") >>> a 5 这可能与您的案例无关,因为它用于受控测试,但在使用用户定义的输入时,请小心使用exe

出于测试目的,我希望直接执行在另一个函数中定义的函数

我可以通过父函数的代码(func_code)访问子函数的code对象,但是当我执行它时,没有返回值


有没有办法从执行代码中获取返回值?

是的,您需要在
exec
语句中进行赋值:

>>> def foo():
...     return 5
...
>>> exec("a = foo()")
>>> a
5

这可能与您的案例无关,因为它用于受控测试,但在使用用户定义的输入时,请小心使用
exec

类似的方法可以奏效:

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 my_exec(code):
    exec('global i; i = %s' % code)
    global i
    return i
这是滥用全局变量来获取跨境数据

>>> my_exec('1 + 2')
3

不用说,您永远不应该允许任何用户输入该函数的输入,因为它会带来极大的安全风险。

以下是一种从执行代码返回值的方法:

def exec_和_return(表达式):
exec(f“”“locals()['temp']={expression}”“”)
返回局部变量()['temp']

我建议你举一个例子,说明你正试图解决的问题。因为我只能将此作为最后的手段。

几年后,但以下片段对我有所帮助:

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
,它在执行后存储了所有局部变量。通过访问它,您可以得到一个类似于返回的东西


我希望它能帮助一些人。

如果我们需要另一个目录中的文件中的函数,例如
我们需要文件my\u py\u file.py中的函数1
位于/home/../另一个\u目录中
我们可以使用以下代码:

def cl_import_函数(函数、py_文件、in_Dir):
... 导入系统
... 系统路径插入(0,在目录中)
... ax=“从%s导入%s%”(py\u文件,a\u func)
... loc={}
... exec(ax,globals(),loc)
... getFx=loc[afunc]
... returngetFx

test=cl\u import\u函数('function1',r'my\u py\u file',r'/home/../other\u directory/'))

测试()

(新手的简单方法…

这里有一个简单代码的解决方案:

#-*-编码:utf-8-*-
输入数学
x=[0]
执行(“x[0]=3*2”)
打印(x[0])#6
这不会得到每个字符的返回值,但是您可以在调用
exec
检索代码中定义的任何变量时提供一个空字典

# Python 3
ex_locals = {}
exec("a = 'Hello world!'", None, ex_locals)
print(ex_locals['a'])
# Output: Hello world!
从:

默认局部变量的作用如下面函数
locals()
所述:不应尝试修改默认局部变量字典如果需要在函数
exec()返回后查看代码对局部变量的影响,请传递显式局部变量字典。


有关更多信息,请参见

我认为您无法使用
exec
执行此操作。您需要像中所描述的那样执行或使用
new
。@DavidMoles:
new
已被弃用,但是
类型
很好,谢谢。这太奇怪了,尤其是您不需要事先声明变量。这对我不起作用
exec('ds\u id=kim\u processors.%s.process(%s)'(function.python\u module,model\u id))
会填充ds\u id,正如我在Django locals调试输出中看到的那样。但是,我随后运行
cursor.execute(““选择e.id作为…其中dataset\u id=%s”“,(ds\u id))
并获取错误“异常类型:NameError异常值:未定义名称“ds\u id”。然而,当地人显示ds_id确实设置为(14)。它的范围有限制吗?@Chris,我不确定问题是什么,但这听起来是一个很好的问题。尝试将其作为问题单独发布,并在此处引用以显示您的尝试。谢谢@wnnmaw这正是我所做的!抱歉,忘记跟进此线程。问题和答案是有更好的导入方法(importlib),重复的问题漂亮地描述了范围问题。感谢您的回复。这不起作用,exec需要使用globals启动,exec(“a=foo()”,globals())谢谢+1.我为得到一个给定字符串的模块的引用而苦苦挣扎,这就是有效的方法。您可以通过将字符串作为参数代码来使用它,它将返回实际的模块。请正确格式化您的代码。虽然您的答案可能有用,但该问题是在6年前提出的,已经有5个答案,尽管没有一个被接受。这对我很有用!谢谢你的提示!这很好。但是您可以使用此代码,而不必为“loc”单独设置字典:exec(代码)return\u workaround=locals()['return\u me']@PatrickMcGloin谢谢您的提示。:)类似的答案已经张贴在那里。最好看看新的问题来回答社区需要你们的地方,因为你们是如此正确。但是,我也想分享一个简单的方法。非常感谢。