我正在使用AST模块在GitHub上进行python源代码的解析,以查看各种功能和库的使用频率。我已经能够成功解析函数调用和库导入,因此我能够捕获诸如import numpy as np
和np.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}"