python - 检测 Python 代码

标签 python instrumentation

我想自动检测在 python 函数中遇到的每个 if 条件。例如,如果我的代码命中:

if x > 2:
    #do something

我想记录/打印“x > 2”到控制台。

我发现这个工具“装备”https://github.com/neuroo/equip/ 但它仅用于功能边界处。我认为我需要能够在字节码指令级别进行检测,以消除这些条件。

目前,我必须在每个 if 条件之后手动 stdout/append,例如

if x > 2:    
    list.append("x>2")

最佳答案

这是一个帮助您入门的简单示例。假设你有这样一个模块:

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 .

关于python - 检测 Python 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47537565/

相关文章:

java - 使用 ActivityUnitTestCase 时出现 RuntimeException,但在 ActivityInstrumentationTestCase2 时不会

python - 删除列表周围的方括号和撇号

python - 计算一个字符串在多个字符串列中的出现次数

python - 安排 scrapy 蜘蛛每 N 分钟运行一次

Python:使用 Hashlib 生成文件的 MD5 哈希

java - 在 list 中指定 -javaagent 选项

python - 将程序的 latin-1 编码输出管道传输到 Python 3 脚本

c - 使用Intel的PIN工具来计算程序中缓存命中/未命中的次数

java - 如何从类路径 * 作为字节数组 * 加载 Java 类以进行字节码注入(inject)?

android - Instrumentation.Activity Monitor 可以查找任何正在启动的 Activity 吗?