我正在尝试对 Python 代码库中的类和函数依赖关系进行一些分析。我的第一步是创建一个 .csv 文件,以便使用 Pythoncsv模块和正则表达式导入 Excel。
我所拥有的当前版本如下所示:
import re
import os
import csv
from os.path import join
class ClassParser(object):
class_expr = re.compile(r'class (.+?)(?:\((.+?)\))?:')
python_file_expr = re.compile(r'^\w+[.]py$')
def findAllClasses(self, python_file):
""" Read in a python file and return all the class names
"""
with open(python_file) as infile:
everything = infile.read()
class_names = ClassParser.class_expr.findall(everything)
return class_names
def findAllPythonFiles(self, directory):
""" Find all the python files starting from a top level directory
"""
python_files = []
for root, dirs, files in os.walk(directory):
for file in files:
if ClassParser.python_file_expr.match(file):
python_files.append(join(root,file))
return python_files
def parse(self, directory, output_directory="classes.csv"):
""" Parse the directory and spit out a csv file
"""
with open(output_directory,'w') as csv_file:
writer = csv.writer(csv_file)
python_files = self.findAllPythonFiles(directory)
for file in python_files:
classes = self.findAllClasses(file)
for classname in classes:
writer.writerow([classname[0], classname[1], file])
if __name__=="__main__":
parser = ClassParser()
parser.parse("/path/to/my/project/main/directory")
Run Code Online (Sandbox Code Playgroud)
这会生成以下格式的 .csv 输出:
class name, inherited classes (also comma separated), file
class name, inherited classes (also comma separated), file
... etc. ...
Run Code Online (Sandbox Code Playgroud)
除了类名之外,我还想开始解析函数声明和定义。我的问题:有没有更好的方法来获取类名、继承类名、函数名、参数名等?
注意:我考虑过使用 Pythonast模块,但我没有使用它的经验,也不知道如何使用它来获取所需的信息,或者它是否可以做到这一点。
编辑:为了回应 Martin Thurau 提供更多信息的请求- 我试图解决这个问题的原因是因为我继承了一个相当冗长(100k+ 行)的项目,该项目的模块、类和函数没有可辨别的结构;它们都作为文件集合存在于单个源目录中。
一些源文件包含数十个相关的类,并且长度超过 10k 行,这使得它们难以维护。我开始对每门课程的相对难度进行分析,并以《搭便车指南》为基础将其包装成更具凝聚力的结构。我对该分析关心的部分内容是类与其文件中其他类的交织程度以及特定类依赖哪些导入或继承的类。
我已经开始实施这一点。将以下代码放入文件中并运行它,并传递要分析的文件或目录的名称。它将打印出它找到的所有类、找到它的文件以及该类的基础。它不是智能的,因此如果您Foo在代码库中定义了两个类,它不会告诉您正在使用哪一个,但它是一个开始。
此代码使用 pythonast模块检查.py文件并查找所有ClassDef节点。然后它使用这个meta包来打印其中的一些内容 - 您将需要安装这个包。
$ pip install -e git+https://github.com/srossross/Meta.git#egg=meta
Run Code Online (Sandbox Code Playgroud)
示例输出,针对django-featured-item运行:
$ python class-finder.py /path/to/django-featured-item/featureditem/
FeaturedField,../django-featured-item/featureditem/fields.py,models.BooleanField
SingleFeature,../django-featured-item/featureditem/tests.py,models.Model
MultipleFeature,../django-featured-item/featureditem/tests.py,models.Model
Author,../django-featured-item/featureditem/tests.py,models.Model
Book,../django-featured-item/featureditem/tests.py,models.Model
FeaturedField,../django-featured-item/featureditem/tests.py,TestCase
Run Code Online (Sandbox Code Playgroud)
代码:
$ pip install -e git+https://github.com/srossross/Meta.git#egg=meta
Run Code Online (Sandbox Code Playgroud)