关于 py-code-health
py-code-health 是面向 Python 代码库维护的技能,用于发现高置信度的死代码和重复代码,并指导清理与合并。它使用 vulture 和 pylint,同时强调核实误报并在修改后运行测试。
主要功能
- 01使用 vulture 检测未使用代码
- 02用置信度筛选并排序结果
- 03使用 pylint 查找重复代码
- 04合并重复逻辑并参数化函数
- 05识别误报并通过白名单处理
- 06清理注释代码并验证测试
适用场景
- 01清理确认未使用的函数和导入
- 02查找多个文件中的重复代码
- 03重构相似逻辑以减少重复
- 04删除代码后验证测试与覆盖率
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ l-mb/ python-refactoring-skills --skill py-code-health安装后在 Claude Code 中输入/py-code-health确认已加载。
详细介绍
Python 代码健康维护
删除无用代码并整合重复内容,让代码库保持整洁且易于维护。
目标
- 检测未使用的代码(函数、类、变量)
- 高置信度地查找并删除无用代码
- 识别文件之间的重复代码
- 将相似代码整合到参数化函数中
- 删除多余的导入和注释掉的代码
所需工具
添加到 [dependency-groups] dev:"vulture"、"pylint"
- vulture:基于 AST 的无用代码检测
- pylint:重复代码检测
权限:先运行 py-quality-setup,配置 .claude/settings.local.json 并授予所有所需工具权限。
无用代码检测
查找未使用的代码
# Using vulture (primary tool)
vulture . # Find all unused code
vulture . --min-confidence 80 # High confidence only
vulture . --min-confidence 80 --sort-by-size # Largest dead code first
vulture . --exclude=tests/,venv/,.venv/ # Exclude directories
# Generate report
vulture . --min-confidence 80 > dead_code_report.txt
解读 Vulture 输出
unused function 'calculate_tax' (80% confidence)
src/billing.py:45
unused class 'LegacyProcessor' (90% confidence)
src/processors.py:123
unused variable 'debug_mode' (60% confidence)
src/config.py:12
置信度级别:
- 60-70%:可能是误报(动态导入、元类等)
- 80-89%:很可能未使用,删除前请验证
- 90-100%:几乎可以确定未使用
处理误报
Vulture 可能会标记实际上正在使用的代码:
1. 动态导入/调用:
# Flagged as unused but called dynamically
def plugin_handler():
pass
# Called via: getattr(module, 'plugin_handler')()
2. 框架约定:
# Django models - fields used by ORM
class User(models.Model):
email = models.EmailField() # May be flagged but used by Django
3. 公共 API:
# Part of library's public API, used by external code
def public_function():
pass
解决方案:
- 添加到白名单文件:
vulture . whitelist.py - 添加注释:
# pragma: no cover或自定义标记 - 接受公共 API 的误报
- 应该使用但尚未使用的代码:
例如,常量、魔术数字、类型定义,甚至函数都可能看起来未被使用。但这实际上可能就是问题所在!(考虑是否存在未完成的重构或其他原因。)
删除看似无用的代码之前,请确认是否存在应该引用它的相似模式。如果存在,请改为修复调用/使用位置。
删除无用代码
# BEFORE - Unused functions cluttering codebase
def old_calculate_price(item): # Last used 2 years ago
return item.cost * 1.1
def deprecated_handler(data): # Replaced by new_handler
pass
# AFTER - Clean, only active code remains
# (Dead code completely removed)
重复代码检测
查找重复内容
# Using pylint (detects similar code blocks)
pylint --disable=all --enable=duplicate-code --recursive=y .
# Configure minimum similar lines (default: 4)
pylint --disable=all --enable=duplicate-code --duplicate-code-min-lines=6 --recursive=y .
# JSON output for parsing
pylint --disable=all --enable=duplicate-code --output-format=json --recursive=y . > duplication.json
解读 Pylint 输出
Similar lines in 2 files
src/auth.py:45-60
src/admin.py:123-138
def validate_credentials(username, password):
if not username or not password:
return False
user = db.get_user(username)
if not user:
return False
return check_password(password, user.password_hash)
整合模式
参数化相似函数
# BEFORE - Duplicate code with slight variations
def process_user(data: dict) -> User:
if not data.get("email"):
raise ValueError("Missing email")
if not data.get("name"):
raise ValueError("Missing name")
return User(email=data["email"], name=data["name"])
def process_admin(data: dict) -> Admin:
if not data.get("email"):
raise ValueError("Missing email")
if not data.get("name"):
raise ValueError("Missing name")
return Admin(email=data["email"], name=data["name"])
# AFTER - Single parametrized function
T = TypeVar('T', User, Admin)
def process_entity(data: dict, entity_class: type[T]) -> T:
if not data.get("email"):
raise ValueError("Missing email")
if not data.get("name"):
raise ValueError("Missing name")
return entity_class(email=data["email"], name=data["name"])
# Usage
user = process_entity(data, User)
admin = process_entity(data, Admin)
提取通用逻辑
# BEFORE - Duplicated validation in multiple functions
def create_user(email: str, age: int) -> User:
if not email or "@" not in email:
raise ValueError("Invalid email")
if age < 0 or age > 150:
raise ValueError("Invalid age")
return User(email=email, age=age)
def update_user(user_id: int, email: str, age: int) -> User:
if not email or "@" not in email:
raise ValueError("Invalid email")
if age < 0 or age > 150:
raise ValueError("Invalid age")
user = get_user(user_id)
user.email = email
user.age = age
return user
# AFTER - Extract common validation
def validate_email(email: str) -> None:
if not email or "@" not in email:
raise ValueError("Invalid email")
def validate_age(age: int) -> None:
if age < 0 or age > 150:
raise ValueError("Invalid age")
def create_user(email: str, age: int) -> User:
validate_email(email)
validate_age(age)
return User(email=email, age=age)
def update_user(user_id: int, email: str, age: int) -> User:
validate_email(email)
validate_age(age)
user = get_user(user_id)
user.email = email
user.age = age
return user
使用配置而不是重复代码
# BEFORE - Similar handlers with different values
def process_csv_file(path: str) -> list:
return parse_file(path, delimiter=",", encoding="utf-8", skip_header=True)
def process_tsv_file(path: str) -> list:
return parse_file(path, delimiter="\t", encoding="utf-8", skip_header=True)
def process_psv_file(path: str) -> list:
return parse_file(path, delimiter="|", encoding="utf-8", skip_header=True)
# AFTER - Configuration-driven
FILE_CONFIGS = {
"csv": {"delimiter": ",", "encoding": "utf-8", "skip_header": True},
"tsv": {"delimiter": "\t", "encoding": "utf-8", "skip_header": True},
"psv": {"delimiter": "|", "encoding": "utf-8", "skip_header": True},
}
def process_file(path: str, file_type: str) -> list:
config = FILE_CONFIGS[file_type]
return parse_file(path, **config)
删除注释掉的代码
注释掉的代码也是一种无用代码:
# BEFORE - Cluttered with old code
def calculate_total(items: list) -> float:
# Old implementation - kept for reference
# total = 0
# for item in items:
# total += item.price * item.quantity
# return total
# Another old version
# return sum(item.price * item.quantity for item in items)
# Current implementation
return sum(item.total_price() for item in items)
# AFTER - Clean, rely on git history
def calculate_total(items: list) -> float:
return sum(item.total_price() for item in items)
理由:Git 历史会保留旧实现。注释掉的代码会造成干扰。
验证清单
-
vulture . --min-confidence 80未报告无用代码(或仅报告已接受的误报) -
pylint --disable=all --enable=duplicate-code未报告超过 6 行的重复代码块 - 不再有注释掉的代码块
- 删除代码后所有测试均通过
- 代码覆盖率保持不变或有所提高
- 已为有意保留的误报创建白名单文件(如有需要)
示例
示例:代码健康清理工作流
1. Scan: vulture . --min-confidence 80; pylint --disable=all --enable=duplicate-code --recursive=y .
2. Found: 5 unused functions (67 lines), 3 duplicate blocks (45 lines)
3. Remove: Verify unused code with Explore agent, delete confirmed dead code
4. Consolidate: Extract duplicates to shared utilities
5. Result: -112 lines total, tests pass, coverage improved to 86%
示例:处理误报
1. Scan: vulture . --min-confidence 80
2. Found: public_api_function flagged as unused (actually part of library API)
3. Create whitelist.py with: public_api_function # Used by external consumers
4. Re-scan: vulture . whitelist.py --min-confidence 80
5. Result: False positive suppressed, real dead code still detected
示例:整合重复的验证逻辑
1. Scan: pylint --disable=all --enable=duplicate-code --recursive=y .
2. Found: Same validation logic in create_user() and update_user()
3. Extract: Create validate_user_data() helper function
4. Update: Both functions now call validate_user_data()
5. Result: -15 lines, single source of truth for validation
相关技能
- 前置条件:py-quality-setup(工具配置)、py-test-quality(删除代码前的安全保障)
- 后续步骤:py-complexity(清理后降低复杂度)
- 另请参阅:py-security(重大更改前检查安全性)
评论
支持 Markdown