如何在 python 程序中注入代码,以便它们可以在 if 语句中打印条件?

How can I inject code in python programs so that they can print the conditions inside the if statement?

我正在寻找一种检测(在内部注入代码)python 程序的方法。 例如,如果程序遇到 if 条件 x > 2,我想在打印到控制台 x > 2if 条件之后自动添加 print 语句.

程序的源代码不可用。

您可以使用 ast 模块,但您仍然需要源代码。如果您只有字节码,则必须使用 uncompyle6 之类的东西才能取回源代码 - 因为您是自动执行此操作,所以源代码是否被混淆并不重要。

假设你有这样一个模块:

def foo(x):
    if x > 100:
        print('big')
    else:
        print('small')


if __name__ == '__main__':
    foo(5)
    foo(500)

如果你执行 foo,你会得到:

small
big

如果测试是 True,现在您想打印每个 if 语句的测试子句。让我们从导入 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 子句,您都打印了测试。像你这样聪明的人可以从这里想出一切。

查看 this video from Pycon 2011