Python中有一个让新手频频踩坑的特性,那就是函数默认参数的求值时机。
很多人在定义函数时,喜欢把可变对象作为默认参数,比如列表或字典。但这样做会引发意料之外的行为,因为默认参数在函数定义时就被求值了,而不是在每次调用时重新创建。
来看一个经典例子:def add_item(item, my_list=[]): my_list.append(item); return my_list。当你连续调用 add_item('a') 和 add_item('b') 时,你会发现返回的是 ['a', 'b'],而不是每次都是新列表。
这是因为默认参数 my_list 指向了同一个列表对象,所有调用共享这个对象。这违背了大多数人的直觉,他们期望每次不传参数时都获得一个全新的空列表。
正确的做法是使用 None 作为占位符,然后在函数内部判断并创建新列表。例如:def add_item(item, my_list=None): if my_list is None: my_list = []; my_list.append(item); return my_list。
这样每次调用不传列表时,都会生成一个独立的列表对象,互不干扰。同样的陷阱也适用于字典和集合等可变类型。
这个规则在 Python 官方文档中有明确说明,属于语言设计中的‘惰性求值’反例。理解这一点,能避免大量生产环境中的隐蔽 Bug。
此外,如果你需要保留默认参数的历史状态,这种特性反而可以巧妙利用,比如做缓存或累加器。但绝大多数场景下,请坚持使用 None 模式。
记住,Python 的默认参数只计算一次,这是函数定义时的动作,而非运行时。把这个原则刻在脑子里,你的代码会更健壮、更可预测。