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

Python函数默认参数为何在调用间保留值?新手技术问询

为什么Python函数的可变默认参数会保留之前的状态?

这绝对是Python新手最容易踩的坑之一!我来给你拆解清楚到底发生了什么:

核心原因:默认参数的初始化时机

你以为每次调用func()的时候,b=set()都会重新创建一个新的空集合?其实不是!Python的函数默认参数是在函数被定义的那一刻初始化的,而不是每次调用函数的时候。

也就是说,当你写下def func(a,b=set()):这行代码时,这个空集合set()就已经被创建出来了,并且会一直复用这个同一个对象——只要你调用函数时没有手动传入b参数,就会用这个已经存在的集合。

结合你的代码一步步看

  1. 第一次调用func([1,1,2,2,3,4])

    • 此时b用的是定义函数时创建的那个空集合set()。
    • 循环过程中,你把每个i都添加到了b里,最后b变成了{1,2,3,4},同时返回的res是第一次出现的元素[1,2,3,4]。
  2. 第二次调用func([1,1,2,2,3,4])

    • 你依然没有传入b参数,所以Python还是用之前那个已经被修改成{1,2,3,4}的集合。
    • 循环里每个i都已经在b里了,所以res里没有添加任何元素,最终返回[]。

你添加print(b)后看到的输出也完全符合这个逻辑:第一次调用前b是空集合,调用后被修改;第二次调用前b已经是{1,2,3,4}了,自然不会有新元素加入res。

怎么解决这个问题?

如果你希望每次调用函数时都使用一个全新的空集合,应该把默认参数设为None,然后在函数内部初始化b:

def func(a, b=None):
    # 如果没有传入b,就创建一个新的空集合
    if b is None:
        b = set()
    res = list()
    for i in a:
        if i not in b:
            res.append(i)
        b |= {i}
    return res

这样每次调用时,只要没传b,都会生成一个新的空集合,就不会出现之前的“残留状态”问题了。

额外提醒

这个坑不止出现在set上,所有可变类型(比如list、dict)作为默认参数时都会有这个问题——因为它们是可变对象,修改会直接改变原对象的状态,影响后续的函数调用。

内容的提问来源于stack exchange,提问作者Mar Ok

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:43:13