使用AST获取有关变量及其类型的信息

时间:2019-04-04 21:03:12

标签: python parsing abstract-syntax-tree

我正在使用AST模块在GitHub上进行python源代码的解析,以查看各种功能和库的使用频率。我已经能够成功解析函数调用和库导入,因此我能够捕获诸如import numpy as npnp.array([1, 2, 3])之类的东西,并记录调用numpy.array的情况(我也可以处理'from'进口)。

我遇到的问题是捕获实例化的呼叫,例如

x = [1, 1, 2, 1, 3]
x.count(1)

我能够提取x.count(1),但是由于我不知道x的类型(列表和字符串都具有count方法),因此我无法完全解析和记录这些函数调用。

关于如何处理此问题的任何想法?我应该尝试保留变量及其内容/类型的运行命名空间,然后尝试找出函数对应的库吗?似乎有太多的复杂性,因为您可以拥有x,y =(len(a),str(b))之类的语句,所以我希望有一种更简单的方法。谢谢!

以下是我如何处理其他部分的内容。代码改编自另一个StackOverflow帖子。

class ParseCall(ast.NodeVisitor):
    def __init__(self):
        self.ls = []
    def visit_Attribute(self, node):
        ast.NodeVisitor.generic_visit(self, node)
        self.ls.append(node.attr)
    def visit_Name(self, node):
        self.ls.append(node.id)

class FindFuncs(ast.NodeVisitor):
    def __init__(self):
        self.funcs = []
    def visit_Call(self, node):
        p = ParseCall()
        p.visit(node.func)
        self.funcs.append(".".join(p.ls))
        ast.NodeVisitor.generic_visit(self, node)

class FindImports(ast.NodeVisitor):
    def __init__(self):
        self.imports = {}
    def visit_Import(self, node):
        for x in node.names:
            if(x.asname): self.imports[x.asname] = x.name
            else: self.imports[x.name] = x.name
    def visit_ImportFrom(self, node):
        for x in node.names:
            if(x.asname): self.imports[x.asname] = f"{node.module}.{x.name}"
            else: self.imports[x.name] = f"{node.module}.{x.name}"

0 个答案:

没有答案