簡體   English   中英

Python:exec()代碼塊和eval()最后一行

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

我試過幾件事:

  1. 通過拆分最后一行,你可以執行第一個塊,然后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) 

    這有效,但如果最后一個語句有多行,則會失敗。

  2. 如果代碼本身被修改,結果存儲為局部變量,則可以恢復該變量; 例如

     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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM