前两天调一个脚本,函数里用 list 当默认参数存中间结果。单测个个 green,串成完整流程却吐出一堆重复数据。排查半天才定位到根因:Python 的默认参数在 def 语句执行时只求值一次,之后每次调用复用的是同一个对象,而不是每次新建。那个 list 在函数定义那一刻就被造出来了,所有调用共享同一份,append 进去的东西跨调用静默累积,像上一个调用的状态在幽灵残留。
这是语言设计特性,不是手滑。dict、set 当默认值同理。最坑的是现象不规律,单测逐个调用全过,整链路才暴露,因为平时谁会连着调同一个函数还指望它每次从空开始。
解法很朴素:默认值写 None,函数体内再判空初始化,或者改用不可变对象。btw 这类 bug 最折磨人的地方在于它不报错,只是悄悄不对,你盯着代码觉得 logically 没问题。写代码还是得敬畏语言语义,别想当然。