x.append(1); return x。其实我下意识觉得每次调用都该拿到个干净的空列表,结果连着调三次,分别吐出来 [1]、[1,1]、[1,1,1]。当场愣了两秒。
想通之后其实简单:Python 的默认参数只在 def 那一行求值一次,之后所有调用共用同一个对象。x=[] 不是"每次调用新建一个空列表",而是"定义时建了一个,大家轮流用"。list、dict、set 这类可变对象(mutable,意思是内容能被原地改)的状态就顺着调用一路往下攒,函数跟记仇似的,上次塞进去的东西下次调用还在。
简单说
正确写法是拿 None 当占位符,在函数体里再初始化:def add_item(x=None): if x is None: x = []。或者干脆用元组这种不可变的。这种坑踩过一回就忘不掉,但也正因为它…,才让人认真琢磨"函数到底有没有副作用"这件事。
线下的习惯是:凡是有状态的默认值,一律挪进函数体里,别在签名上偷懒。