AI 一次性生成的代码里,重复逻辑出现频率很高。本文用一段包含三类重复的 Python 样本,讲清对应的精简顺序:先抽函数消除同构重复,再用参数化合并近似函数,最后用配置表替换散落的常量。核心结论是,精简必须在测试通过之后做,且只做「改一处要动几处」的那类重复,纯长相相似的重复不动。下面每个方法都给出增删前后的代码对照和判定标准,并附常见失败与修复方向。先确认测试是否跑通,再动手删重复。

一、先看结论:什么重复值得精简
下面这张表给出重复类型的判定顺序,从最值得改到最后值得改。判定标准只有一条:改一处的时候,要不要同时改几处。
| 重复类型 | 典型表现 | 是否值得精简 |
|---|---|---|
| 同构重复 | 同一段逻辑复制三四遍,写法一致 | 值得,抽函数 |
| 近似重复 | 几个函数只差参数或阈值 | 值得,合并加参数 |
| 常量散落 | 同一个数字在多处硬编码 | 值得,集中定义 |
| 形似神不似 | 写法像但语义不同 | 不值得,动了反而更乱 |

这个顺序的依据是收益与风险的比值。同构重复的收益最直观,风险最低;形似神不似的重复看起来省事,实际会把两个不同语义绑在一起,后期改动会牵连。判断时先问「这两个东西将来会不会一起改」,会就合并,不会就各留各的。
二、环境确认与最小示例
先给一段 AI 通常会写出来、重复密度很高的代码。样本基于 Python 3.10 标准库,不涉及第三方依赖;Python 版本差异对下面的精简结论没有影响。以下为预期结果说明,未在本机执行,按 Python 官方文档推断。
# 确认 Python 版本后执行下面的脚本
python --version
# 样本:三个平台的折扣计算,AI 经常生成为三段几乎一样的代码
def discount_a(amount):
if amount > 1000:
return amount * 0.9
return amount
def discount_b(amount):
if amount > 2000:
return amount * 0.85
return amount
def discount_c(amount):
if amount > 3000:
return amount * 0.8
return amount
这三段代码都能跑,但已经命中了「近似重复」和「常量散落」两类问题。精简前先确认测试或手动验证已经通过,没有验证就改,出问题无法判断是精简引入的还是原本就有。这一步的检查很关键。想在线对比精简前后的输出差异,可用 在线代码实例 验证实际结果。
三、方法一:同构重复抽成函数
第一档精简针对写法完全一致、只差数据的重复。做法是把变化的部分当作参数抽出去,只保留一份实现。
# 精简后:三个平台共用同一份实现,差异通过参数传入
MIN_AMOUNT_A = 1000 # A 平台的折扣门槛,改这里不用再动函数定义
MIN_AMOUNT_B = 2000 # B 平台的折扣门槛,与 A 相互独立
MIN_AMOUNT_C = 3000 # C 平台的折扣门槛
DISCOUNT_A = 0.10 # A 平台的优惠比例,10% 表示打九折
DISCOUNT_B = 0.15
DISCOUNT_C = 0.20
def calc_discount(amount, min_amount, discount):
"""按门槛与优惠比例计算折后金额。"""
if amount > min_amount:
return amount * (1 - discount)
return amount
抽函数的判定标准很直接:函数体里出现几处差一个数字的地方,就说明该把这些数字提成参数。修复方向不是把三段合并成一个大函数,而是保留三个入口、共用一份实现,接口不变,调用方无感。
四、方法二:近似重复合并加参数
第二档针对函数近似、只差门槛或比例的情况。合并之后三个入口仍然存在,但底层实现只有一份。
# 合并后的三个入口:参数各自独立,接口与原先完全一致
def discount_a(amount):
return calc_discount(amount, MIN_AMOUNT_A, DISCOUNT_A)
def discount_b(amount):
return calc_discount(amount, MIN_AMOUNT_B, DISCOUNT_B)
def discount_c(amount):
return calc_discount(amount, MIN_AMOUNT_C, DISCOUNT_C)
合并的判定标准是「将来会不会一起改」。三个平台的折扣规则通常由同一份运营策略调整,命中这个条件就合并;如果某个平台明确要单独维护自己的规则,保留独立函数更安全。这个边界需要你根据业务判断,脚本判断不了。
五、方法三:常量集中定义与边界检查
第三档处理散落的魔法数字。把阈值和比例集中到模块顶部,后续调整只改一处。同时给出一段边界更完整的实现,补上非正数输入的处理。
# 精简后的完整实现:常量集中 + 边界检查
def calc_discount_safe(amount, min_amount, discount):
"""计算折后金额,并挡住非法输入。"""
# 边界:负数或 None 直接返回原价,避免在下游产生更难查的异常
if not amount or amount <= 0:
return amount
if amount > min_amount:
return amount * (1 - discount)
return amount
print(calc_discount_safe(1500, MIN_AMOUNT_A, DISCOUNT_A))
# 1500 > 1000,命中 A 门槛,打九折后预期返回 1350
常量定义的判定标准是:同一数字在文件里出现两次以上就提取。这里要提醒的是,精简不等于无限抽象,如果某段重复只在单个函数内出现两次,抽出来反而增加跳转成本,保持原样更好。想把精简做成习惯,可以先挑一个重复最明显的模块试手,把「改一处要不要动几处」这句话记在旁边对照。判断标准始终不变:两个东西将来会不会一起改,会就合并,不会就各留各的。所以代码精简做的是减法,不是重构,拿不准的重复宁可先留着。抽完之后有一件必须做的事:把三个入口在几组典型输入下的输出,和精简前逐一对一遍。比较可靠的做法是用断言把预期值固定下来,例如 assert calc_discount(1500, MIN_AMOUNT_A, DISCOUNT_A) == 1350,让程序自己报错,而不是靠肉眼看输出。这一步做完了再往下做第二档,顺序不能倒。函数与常量的命名能查 Python 速查手册。
总结
AI 写的代码重复太多怎么精简,答案是按判定顺序处理:同构重复抽成函数,只留一份实现;近似重复合并加参数,保留原接口;常量散落集中定义,调整只改一处。精简前必须确认测试或手动验证已通过,精简后要跑一遍原样例,确认输出与精简前一致。判断标准始终是「改一处要不要动几处」,以及「将来会不会一起改」,两个条件都命中才动手,否则宁可保留重复。
延伸学习
想在编程狮系统学 AI 辅助编程与代码重构,可以顺着下面三篇深入:
常见问题
Q:精简之后输出和之前不一样,说明什么?
A:说明精简引入了行为变化,很可能合并时把两个语义不同的分支揉在了一起。此时不要继续调整精简,先回退到精简前的版本,对照输出差异定位具体分支,再决定是改精简方案还是保持原样。
Q:重复一定要消除吗?
A:不。判定标准是「改的时候要不要同时改几处」以及「将来会不会一起改」。两个条件都命中才合并;只是写法相似、语义不同的重复,合并会让后续改动牵连更多地方,保持原样更好。
Q:什么情况下不要抽函数?
A:同一段重复只在单个函数内出现一两次时,抽出来会增加跳转成本,反而更难读。另外,如果抽出的函数会在两个语义完全不同的场景被调用,语义就已经被绑死在一起了,这种情况下保持重复更合适。
Q:精简和重构是一回事吗?
A:不完全是。精简只处理重复,不改外部行为;重构的范围更广,可能包含接口调整。做精简时应该严守「输出不变」这条线,一旦输出变化就说明已经越界到重构了,需要单独评估风险。

TRAE-AI编程



