我想自动检测python函数中遇到的每个if条件。例如,如果我的代码命中:
if x > 2:
#do something
我想将“x> 2”录制/打印到控制台。
我发现这个工具“装备”https://github.com/neuroo/equip/ 但它只是在功能边界的实验。我想我需要能够在字节码指令级进行检测以获得这些条件。
目前,我必须在每个if条件之后手动stdout / append,如
if x > 2:
list.append("x>2")
答案 0 :(得分:6)
这是一个简单的例子,可以帮助您入门。假设你有一个这样的模块:
def foo(x):
if x > 100:
print('big')
else:
print('small')
if __name__ == '__main__':
foo(5)
foo(500)
如果你执行foo,你会得到:
small
big
现在,如果测试为if
,则要打印每个True
语句的test子句。让我们先导入foo:
>>> import foo
然后获取源代码:
>>> source = inspect.getsource(foo)
让我们解析源代码以获得抽象语法树:
>>> tree = ast.parse(source)
下一步是定义一个将修改树的NodeTransformer:
>>> class IfTransformer(ast.NodeTransformer):
def visit_If(self, node):
new_node = ast.Expr(value=ast.Call(
func=ast.Name(id='print', ctx=ast.Load()),
args=[ast.Str(s=astunparse.unparse(node.test))],
keywords=[]
))
node.body.insert(0, new_node)
return ast.fix_missing_locations(node)
为了修改树,我们让IfTransformer
访问所有节点:
>>> IfTransformer().visit(tree)
然后你可以编译并执行你的新资源:
>>> exec(compile(tree, 'foo.py', 'exec'))
(__name__ == '__main__')
small
(x > 100)
big
对于测试为True的每个if
子句,您打印了测试。像你这样聪明的人可以从这里找出所有的东西。