Python:exec()代码块和eval()最后一行

时间:2016-09-07 21:32:42

标签: python

我有一个包含一行或多行(可信)Python代码的字符串文字,我想exec()该块,同时捕获最后一行的结果。更具体地说,我希望函数exec_then_eval返回以下内容:

code = """
x = 4
y = 5
x + y
"""

assert exec_then_eval(code) == 9

我尝试了几件事:

  1. 通过拆分最后一行,你可以执行第一个块,然后判断最后一行; e.g。

    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)
    

    这样可行,但如果最后一个语句有多行,则会失败。

  2. 如果代码本身被修改,结果存储为局部变量,则可以恢复该变量; e.g。

    code = """
    x = 4
    y = 5
    z = x + y
    """
    
    globals = {}
    locals = {}
    exec(code, globals, locals)
    assert locals['z'] == 9
    

    再次,这是有效的,但前提是您能够以一般方式首先解析代码块并进行适当修改。

  3. 是否有一种简单的方法来编写一般的exec_and_eval函数?

1 个答案:

答案 0 :(得分:5)

根据@ kalzekdor关于使用UPDATE Family SET FullAddress = StreetAddress + ', ' + City + ', ' + State + ', ' + ZipCode; 模块的建议,我提出了这个与上面发布的@vaultah解决方案类似的解决方案:

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)