duplicate-code-modified¶
类别: 重复代码
严重程度: Info
触发方式: pyscn analyze, pyscn check --select clones
检测内容¶
标记共享大部分结构但有添加、删除或修改语句的代码块(Type-3 克隆,相似度 >= 0.70)。默认禁用;将 "type3" 添加到 clones.enabled_clone_types 可启用。
为什么这是一个问题¶
近似重复是真实代码库中最常见的克隆类型,通常也是最难清理的。两个函数做的事情几乎相同,但其中一个多了一步验证或错误处理路径略有不同。共享部分应存在于一处;不同之处应该是调用点之间唯一的差异。
如果不加处理,修改克隆会逐渐偏离:一处副本修复了 bug,另一处没有;一处新增了功能,另一处被遗忘。审查者不再信任外观相似的代码行为确实相同。
此规则为 Info 级别,因为正确的重构不像 Type-1 或 Type-2 克隆那样机械化 — 有时差异本身就是重点,合并反而会损害清晰度。将发现视为值得查看的候选项,而非自动缺陷。
示例¶
def export_users_csv(users, path):
with open(path, "w") as f:
writer = csv.writer(f)
writer.writerow(["id", "name", "email"])
for u in users:
writer.writerow([u.id, u.name, u.email])
def export_orders_csv(orders, path):
with open(path, "w") as f:
writer = csv.writer(f)
writer.writerow(["id", "total", "status"])
for o in orders:
if o.status != "draft":
writer.writerow([o.id, o.total, o.status])
修正示例¶
提取通用脚手架,将表头、行格式和过滤条件参数化。
def export_csv(rows, path, header, to_row, keep=lambda _: True):
with open(path, "w") as f:
writer = csv.writer(f)
writer.writerow(header)
for row in rows:
if keep(row):
writer.writerow(to_row(row))
def export_users_csv(users, path):
export_csv(users, path, ["id", "name", "email"],
lambda u: [u.id, u.name, u.email])
def export_orders_csv(orders, path):
export_csv(orders, path, ["id", "total", "status"],
lambda o: [o.id, o.total, o.status],
keep=lambda o: o.status != "draft")
选项¶
| 选项 | 默认值 | 说明 |
|---|---|---|
clones.type3_threshold |
0.70 |
一对代码被报告为修改克隆所需的最低相似度。 |
clones.enabled_clone_types |
["type1","type2","type4"] |
添加 "type3" 以启用此规则。 |
clones.similarity_threshold |
0.65 |
在按类型阈值之前应用的全局下限。 |
clones.min_lines |
5 |
最小片段大小(行数)。 |
clones.min_nodes |
10 |
最小片段大小(AST 节点数)。 |