[英]Python: exec() a code block and eval() the last line
我有一个字符串文字包含一行或多行(可信)Python代码,我想exec()
块,同时捕获最后一行的结果。 更具体地说,我想要一个函数exec_then_eval
,它返回以下内容:
code = """
x = 4
y = 5
x + y
"""
assert exec_then_eval(code) == 9
我试过几件事:
通过拆分最后一行,你可以执行第一个块,然后eval最后一行; 例如
def exec_then_eval(code): first_block = '\\n'.join(code.splitlines()[:-1]) last_line = code.splitlines()[-1] globals = {} locals = {} exec(first_block, globals, locals) return eval(last_line, globals, locals)
这有效,但如果最后一个语句有多行,则会失败。
如果代码本身被修改,结果存储为局部变量,则可以恢复该变量; 例如
code = """ x = 4 y = 5 z = x + y """ globals = {} locals = {} exec(code, globals, locals) assert locals['z'] == 9
再次,这是有效的,但前提是你能够以一般方式首先解析代码块并适当地修改它。
有没有一种简单的方法来编写一般的exec_and_eval
函数?
根据@ kalzekdor关于使用ast
模块的建议,我提出了这个解决方案,它与上面发布的@vaultah解决方案的精神相似:
import ast
def exec_then_eval(code):
block = ast.parse(code, mode='exec')
# assumes last node is an expression
last = ast.Expression(block.body.pop().value)
_globals, _locals = {}, {}
exec(compile(block, '<string>', mode='exec'), _globals, _locals)
return eval(compile(last, '<string>', mode='eval'), _globals, _locals)
它还通过@ vaultah的一组很好的测试用例:
exec_then_eval('''x = 4
y = 5
x + y''')) # 9
exec_then_eval('''x = 4
y = 5;x + y''')) # 9
exec_then_eval('''x = 4
y = 5;(
x + y *
2)''') # 14
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.