在Python编程中,函数默认参数是一个看似简单却暗藏玄机的特性。
许多初学者会认为默认参数在每次函数调用时都会被重新创建,但事实并非如此。
默认参数的值只在函数定义时被计算一次,随后每次调用都会共享同一个对象。
这一特性最经典的陷阱出现在使用可变对象作为默认参数时,比如列表或字典。
请看这个例子:def add_item(item, my_list=[]): my_list.append(item); return my_list。
连续调用 add_item(1)、add_item(2) 和 add_item(3),你会发现返回的列表是 [1, 2, 3] 而非每次都是新列表。
这是因为默认参数 my_list 指向了同一个列表对象,每次追加操作都在修改这个共享对象。
正确的做法是使用 None 作为默认值,然后在函数内部进行判断和初始化。
改写为:def add_item(item, my_list=None): if my_list is None: my_list = []; my_list.append(item); return my_list。
这样每次调用时若未传入 my_list,都会创建一个全新的列表对象,避免了数据污染。
同样的原理也适用于字典、集合等其他可变类型,以及自定义类的实例对象。
对于不可变类型如整数、字符串和元组,由于它们无法被修改,这个陷阱不会显现。
但如果你不小心修改了默认参数指向的可变对象,bug 可能隐藏得很深,难以排查。
Python 官方文档和众多风格指南都明确建议:不要使用可变对象作为函数默认参数。
理解这一机制后,你还能利用它来实现缓存或记忆化功能,但需谨慎使用。
总而言之,记住默认参数的求值时机是定义时而非调用时,这是写出健壮代码的关键。