Python函数默认可变参数值异常变更问题咨询
Python函数默认参数为可变对象时的异常现象解析与解决办法
问题原因
Python中,函数的默认参数是在函数定义的那一刻就完成初始化的,而非每次调用函数时重新创建。对于列表、字典这类可变对象,函数对象会一直保留对这个默认值的引用——所有不传入该参数的函数调用,都会共享同一个可变对象实例。
以案例2为例:
- 第一次调用
func1()时,使用的是定义函数时创建的空列表,执行a.append(2)后列表变为[2]; - 第二次调用
func1()时,依然复用这个已被修改的列表,再次append后变为[2,2]; - 后续调用以此类推,导致每次返回的都是同一个不断被修改的列表。
案例1的递归调用同理:每次递归未传入a参数时,都会复用同一个默认列表,最终a中会积累2、3、4三个元素,而非预期的仅包含5。
解决办法
核心思路是避免直接将可变对象作为默认参数,改为在函数内部动态创建新的可变对象实例。
方案1:用None作为默认占位符,函数内部初始化
这是通用度最高的解决方式,适用于绝大多数场景:
案例2修正代码:
def func1(a=None): # 未传入a时,创建新的空列表 if a is None: a = [] a.append(2) return a print(func1()) # 输出 [2] print(func1()) # 输出 [2] print(func1()) # 输出 [2]
案例1修正代码:
def func1(x, a=None): if a is None: a = [] if x == 5: a.append(x) print(a) return x += 1 a.append(x) func1(x) func1(1) # 输出 [5]
方案2:递归场景下主动传入新实例(按需选择)
如果是递归调用场景,也可以在每次递归时主动传入新的列表实例,避免共享默认参数:
def func1(x, a = []): if x == 5: a.append(x) print(a) return x += 1 # 每次递归传入新列表,基于当前a复制后添加元素 func1(x, a + [x]) func1(1) # 输出 [5]
内容的提问来源于stack exchange,提问作者Ritik
相关产品推荐
相关产品推荐

