x86*_*-64 0 python instrumentation python-2.7
我正在寻找一种方法来检测(在其中注入代码)python 程序。例如,如果程序满足if条件x > 2,我想在打印到控制台的条件print后面自动添加一条语句。ifx > 2
该程序的源代码不可用。
您可以使用该ast模块,但仍然需要源代码。如果您只有字节码,则必须使用类似uncompyle6之类的东西才能取回源代码 - 因为您是自动执行此操作,所以源代码是否被混淆并不重要。
假设你有一个这样的模块:
def foo(x):
if x > 100:
print('big')
else:
print('small')
if __name__ == '__main__':
foo(5)
foo(500)
Run Code Online (Sandbox Code Playgroud)
如果你执行 foo,你会得到:
small
big
Run Code Online (Sandbox Code Playgroud)
if现在,如果测试是 ,您想要打印每个语句的测试子句True。让我们从导入 foo 开始:
>>> import foo
Run Code Online (Sandbox Code Playgroud)
然后获取源码:
>>> source = inspect.getsource(foo)
Run Code Online (Sandbox Code Playgroud)
让我们解析源代码以获得抽象语法树:
>>> tree = ast.parse(source)
Run Code Online (Sandbox Code Playgroud)
下一步是定义一个将修改树的 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)
Run Code Online (Sandbox Code Playgroud)
为了修改树,我们访问IfTransformer所有节点:
>>> IfTransformer().visit(tree)
Run Code Online (Sandbox Code Playgroud)
然后你可以编译并执行你的新源:
>>> exec(compile(tree, 'foo.py', 'exec'))
(__name__ == '__main__')
small
(x > 100)
big
Run Code Online (Sandbox Code Playgroud)
if对于测试为 True 的每个子句,您都会打印测试。像你这样聪明的人,从这里就能弄清楚一切。
| 归档时间: |
|
| 查看次数: |
3270 次 |
| 最近记录: |