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

如何在python程序中注入代码,以便它们可以在if语句中打印条件?,python,python-2.7,instrumentation,Python,Python 2.7,Instrumentation,我正在寻找一种插入python程序的方法。 例如,如果程序点击if条件x>2,我想在打印到控制台x>2的if条件后自动添加print语句 程序的源代码不可用。您可以使用ast模块,但仍然需要源代码。如果您只有字节码,那么必须使用类似的方法才能取回源代码-因为您是自动执行此操作的,所以源代码是否被混淆并不重要 假设您有这样一个模块: def foo(x): if x > 100: print('big') else: print('small'

我正在寻找一种插入python程序的方法。 例如,如果程序点击
if
条件
x>2
,我想在打印到控制台
x>2
if
条件后自动添加
print
语句


程序的源代码不可用。

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

假设您有这样一个模块:

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


if __name__ == '__main__':
    foo(5)
    foo(500)
如果你执行foo,你会得到:

small
big
现在,如果测试为
True
,则需要打印每个
if
语句的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
对于测试为真的每个
if
子句,您都会打印测试。像你这样聪明的人可以从这里弄明白一切


签出。

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

假设您有这样一个模块:

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


if __name__ == '__main__':
    foo(5)
    foo(500)
如果你执行foo,你会得到:

small
big
现在,如果测试为
True
,则需要打印每个
if
语句的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
对于测试为真的每个
if
子句,您都会打印测试。像你这样聪明的人可以从这里弄明白一切


检查。

你的意思是没有在代码中明确使用
日志记录
模块还是使用调试器?@chepner是的,没有这些。我打算在执行if语句时(或者在未执行if语句时)记录它们并打印它们的条件。不寻找调试器。为什么不在if之后添加print语句?@user1767754我该怎么做?给定一个自定义python程序,我不知道if条件是什么?我想要自动化。@AliAhsan那么也许你应该在你的问题中清楚地表明,你想要在一个你无法访问源代码的程序上得到这个结果。同样,不要说您想添加一个
print
语句,因为这会让您觉得您只是想在代码中编写一个
print
语句,与自动打印任何条件测试的值相反。您的意思是不在代码中显式使用
日志记录
模块还是不使用调试器?@chepner是的,没有这些。我打算在执行if语句时(或者在未执行if语句时)记录它们并打印它们的条件。不寻找调试器。为什么不在if之后添加print语句?@user1767754我该怎么做?给定一个自定义python程序,我不知道if条件是什么?我想要自动化。@AliAhsan那么也许你应该在你的问题中清楚地表明,你想要在一个你无法访问源代码的程序上得到这个结果。同样,不要说您想添加一个
print
语句,因为这会让您觉得您只是想在代码中编写一个
print
语句,与自动打印任何条件测试的值相反。值得指出的是,除了
ast
模块外,需要导入
inspect
astunparse
才能运行此示例:)值得指出的是,除了
ast
模块外,需要导入
inspect
,并且
astunbrase
运行此示例:)