在函数的代码对象上使用Python exec时,如何获取返回值?
出于测试目的,我希望直接执行在另一个函数中定义的函数 我可以通过父函数的代码(func_code)访问子函数的code对象,但是当我执行它时,没有返回值在函数的代码对象上使用Python exec时,如何获取返回值?,python,function,return,exec,Python,Function,Return,Exec,出于测试目的,我希望直接执行在另一个函数中定义的函数 我可以通过父函数的代码(func_code)访问子函数的code对象,但是当我执行它时,没有返回值 有没有办法从执行代码中获取返回值?是的,您需要在exec语句中进行赋值: >>> def foo(): ... return 5 ... >>> exec("a = foo()") >>> a 5 这可能与您的案例无关,因为它用于受控测试,但在使用用户定义的输入时,请小心使用exe
有没有办法从执行代码中获取返回值?是的,您需要在
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谢谢您的提示。:)类似的答案已经张贴在那里。最好看看新的问题来回答社区需要你们的地方,因为你们是如此正确。但是,我也想分享一个简单的方法。非常感谢。