如何修复Python Pylint输出解析脚本:未保存数据集且仅分析单文件
问题
尝试编写一个Pylint解析器,针对指定Python项目提取代码异味数量、评分信息,分析项目中每个Python文件并生成包含项目名称、代码异味数、评分的DataFrame。但编写的脚本仅分析了setup.py一个文件,且无法生成并保存数据集,仅打印Pylint控制台输出。
原代码片段:
import os import pandas as pd from pylint.lint import Run def pylint_project(project_name): global project_df pylint_options = ["--disable=F0010"] python_files = [f for f in os.listdir(project_name) if f.endswith('.py')] for file in python_files: file_path = os.path.join(project_name, file) pylint_output = Run([file_path] + pylint_options) smell_count = pylint_output.lstrip().split()[1] score = pylint_output.split()[-2] project_df = pd.DataFrame({ "project_name": [project_name], "smell_count": [smell_count], "score": [score] }) return project_df path = "path/to/analyze" com = pylint_project(path) com.to_csv("path/to/save")
控制台输出:
********* Module setup E:\python_projects\machine_learning_projects\alibi\setup.py:17:0: C0301: Line too long (110/100) (line-too-long) E:\python_projects\machine_learning_projects\alibi\setup.py:1:0: C0114: Missing module docstring (missing-module-docstring) E:\python_projects\machine_learning_projects\alibi\setup.py:4:0: C0116: Missing function or method docstring (missing-function-docstring) E:\python_projects\machine_learning_projects\alibi\setup.py:5:48: C0103: Variable name "f" doesn't conform to snake_case naming style (invalid-name) E:\python_projects\machine_learning_projects\alibi\setup.py:10:0: W0122: Use of exec (exec-used) E:\python_projects\machine_learning_projects\alibi\setup.py:10:5: R1732: Consider using 'with' for resource-allocating operations (consider-using-with) E:\python_projects\machine_learning_projects\alibi\setup.py:10:5: W1514: Using open without explicitly specifying an encoding (unspecified-encoding) E:\python_projects\machine_learning_projects\alibi\setup.py:34:18: E0602: Undefined variable '__version__' (undefined-variable) ------------------------------------------------------------------ Your code has been rated at 0.00/10 (previous run: 0.00/10, +0.00
修复方案
核心问题分析
- 错误处理Pylint输出:
Run类默认将输出打印到控制台,且返回值不是文本字符串,无法直接用字符串方法解析。 - 未递归遍历文件:
os.listdir()仅遍历一级目录,无法检测子目录中的Python文件。 - 数据被循环覆盖:每次循环重新创建
project_df,仅保留最后一个文件的结果。 - 不必要的全局变量:
global project_df污染全局命名空间,不符合代码规范。
修复后的完整代码
import os import pandas as pd from pylint.lint import Pylinter from pylint.reporters.text import TextReporter from io import StringIO def pylint_project(project_name): # 初始化列表存储所有文件的分析数据 data = [] # 递归遍历项目中所有Python文件 for root, _, files in os.walk(project_name): for file in files: if file.endswith('.py'): file_path = os.path.join(root, file) # 初始化Pylinter并配置 linter = Pylinter() linter.load_default_plugins() linter.disable("F0010") # 捕获输出,避免打印到控制台 output_buffer = StringIO() reporter = TextReporter(output_buffer) linter.set_reporter(reporter) # 执行代码分析 linter.check([file_path]) linter.generate_reports() # 从Pylint统计数据中提取关键信息 stats = linter.stats # 计算总代码异味数:错误+警告+重构建议+规范问题 smell_count = stats['error'] + stats['warning'] + stats['refactor'] + stats['convention'] # 获取全局评分 score = round(stats['global_note'], 2) # 收集当前文件的分析结果 data.append({ "project_name": project_name, "file_path": file_path, "smell_count": smell_count, "score": score }) # 生成最终DataFrame project_df = pd.DataFrame(data) return project_df # 使用示例 path = "path/to/analyze" result_df = pylint_project(path) result_df.to_csv("pylint_analysis_result.csv", index=False)
关键修改说明
- 使用Pylint原生API:通过
Pylinter类直接获取分析统计数据,无需解析控制台输出,结果更可靠。 - 递归遍历文件:用
os.walk()遍历所有子目录,确保覆盖项目中所有Python文件。 - 数据批量收集:用列表存储每个文件的分析结果,最后统一生成DataFrame,保留所有文件的信息。
- 新增文件路径字段:添加
file_path列,方便定位具体文件的代码问题。 - 关闭控制台输出:通过
StringIO捕获Pylinter输出,避免冗余打印。
内容的提问来源于stack exchange,提问作者Giammaria GIORDANO
相关产品推荐
相关产品推荐

