首页 > 解决方案 > 获取 eval 使用的变量

问题描述

您好,我正在尝试获取 eval 表达式使用的变量列表。我设法使用该mock模块使某些东西起作用:

import mock

def get_eval_vars(expr):
    # Use a mock dictionary to check which items are called
    mock_var = mock.MagicMock()
    eval(expr, {"__builtins__": {}}, mock_var)
    return [args[0][0] for args in mock_var.__getitem__.call_args_list]

print(get_eval_vars("a+b+10")) # Correctly outputs [a, b]
print(get_eval_vars("a<10"))   # Raises TypeError: '<' not supported between instances of 'MagicMock' and 'int'

但是,正如评论中所解释的,模拟会引发错误,因为在 MagicMock 中未定义不等式。查看模拟问题 #196似乎他们没有计划改变这一点。

是否有任何正确的方法来覆盖 MagicMock 的不等式运算符?除了使用模拟之外,还有其他选择吗?

标签: pythonpython-mock

解决方案


好吧,我自己设法做到了这一点ast

import ast

def get_eval_vars(expr):
    st = ast.parse(expr, mode="eval")
    return [node.id for node in ast.walk(st) if isinstance(node,ast.Name) and isinstance(node.ctx, ast.Load)]

print(get_eval_vars("a+b+10")) # Correctly outputs [a, b]
print(get_eval_vars("a<10"))   # Correctly outputs [a]

推荐阅读