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

Python函数参数默认值内存机制疑问:为何列表默认值会保留修改?

问题重现

def a(l=[]):
    print(l)
    l.append('something')

a()     # []
a()     # ['something']

第一次调用函数a后,直觉上会认为局部变量l和它绑定的列表对象应该被销毁——毕竟函数执行完局部作用域消失,l这个名称也不存在了,没有引用指向堆里的列表对象,它应该被垃圾回收。

但实际运行结果是:第二次调用a()时,输出的不是空列表,而是['something'],仿佛第一次调用修改了函数本身的默认参数。

原本以为每次调用函数时,默认参数会重新创建,但事实并非如此。核心疑问是:这背后的运行机制是什么?为什么函数没执行时,参数默认值就已经存在内存里?

背后的运行机制

Python里函数的默认参数是在函数定义的时候创建的,而不是每次调用函数时。

当你写下def a(l=[])这行代码时,Python解释器就会创建这个空列表对象,并把它和函数a的默认参数绑定在一起,这个对象会被存在函数对象的__defaults__属性里(你可以直接打印a.__defaults__看到它)。

每次调用a()且不传参数时,Python不会重新创建新的空列表,而是直接复用这个已经存在的列表对象。第一次调用时,你给这个列表添加了元素,第二次调用自然会看到修改后的结果。

至于为什么局部变量l销毁后,列表对象还存在?因为函数a本身的__defaults__属性还引用着这个列表,垃圾回收机制不会回收还有引用的对象,所以它会一直存在,直到函数对象本身被销毁。

正确的写法

如果想每次调用函数时都使用全新的空列表,应该把默认值设为None,然后在函数内部初始化:

def a(l=None):
    if l is None:
        l = []
    print(l)
    l.append('something')

a()     # []
a()     # []

这样每次调用a()时,都会在函数内部创建新的空列表,避免了默认参数被复用的问题。

内容的提问来源于stack exchange,提问作者Dmitriy Neledva

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 09:05:24