You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 15:15:35