因为 Python 函数的默认参数值在函数定义时只求值一次,作为函数对象的属性保存,之后所有调用共享同一个对象。可变对象(list、dict)被修改后,修改会跨调用累积,产生难以察觉的 bug。
def add_item(item, lst=[]): # lst 在定义时创建,全局共享
lst.append(item)
return lst
add_item(1) # [1]
add_item(2) # [1, 2] —— 期望是 [2],实际是共享列表被污染
正确写法是用不可变哨兵值(通常 None)做默认值,函数体内再创建新对象:
def add_item(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lst
易错点:def f(t=time.time()) 之类"默认时间戳"也是同一陷阱——值在定义时刻固化,不是每次调用取当前时间。追问方向:为什么不可变默认值(int、str、tuple)没这个问题(共享但无法原地修改,赋值只是重新绑定);默认参数存于 func.__defaults__,可现场验证共享行为。