关于Python3.6默认参数值的困惑:两段示例代码差异疑问
Python默认参数的绑定时机:为什么两个函数的执行结果截然不同?
Hey,这绝对是Python里最容易踩的经典“坑”之一,核心原因就在于Python的默认参数是在函数定义时就完成求值,而非每次调用函数时重新创建。咱们一步步拆解你的问题:
为什么第一段代码里的L=[]不会在每次调用时重置?
先把第一段代码整理清晰:
def f(a, L=[]): L.append(a) return L print(f(1)) # 输出: [1] print(f(2)) # 输出: [1, 2] print(f(3)) # 输出: [1, 2, 3]
当Python加载这个f函数的时候,默认参数L=[]对应的空列表就已经被创建出来了——它是一个全局唯一的列表对象。之后每次调用f时如果没有手动传入L,都会复用这个已经存在的列表:
- 第一次调用
f(1):用默认的空列表,追加1后返回[1],此时这个列表已经被修改; - 第二次调用
f(2):依然使用那个已经变成[1]的列表,追加2后返回[1,2]; - 第三次调用同理,最终得到累积后的列表。
为什么第二段代码用L=None就能解决问题?
再看第二段修复后的代码:
def f(a, L=None): if L is None: L = [] L.append(a) return L print(f(1)) # 输出: [1] print(f(2)) # 输出: [2] print(f(3)) # 输出: [3]
None是Python里的不可变单例对象,函数定义时绑定它没问题,但关键在于每次调用函数时都会执行内部的判断逻辑:
- 当没有传入
L时,L会被设为默认的None,这时代码会创建一个全新的空列表; - 每次调用都会生成独立的新列表,所以每次返回的都是只包含当前参数的列表,不会累积之前的结果。
一句话总结
- Python默认参数的求值时机是函数定义阶段,而非调用阶段;
- 如果默认参数是可变对象(列表、字典等),会在多次调用间复用同一个对象,导致意外的状态保留;
- 通用解决方案是用不可变对象(比如
None)作为默认值,在函数内部按需创建可变对象。
内容的提问来源于stack exchange,提问作者FriWant
相关产品推荐
相关产品推荐

