Python类可变默认参数初始化异常:新实例默认值不符合预期
问题核心原因
这是Python中可变类型作为函数默认参数的经典设计特性(常被称为陷阱):
- Python的函数默认参数在函数定义阶段就会被创建并绑定到函数对象本身,而非每次调用函数时重新生成
- 如果默认参数是列表、字典、类实例这类可变类型,所有未显式传参的函数调用,都会共享同一个可变对象
针对你的代码现象解释
第一种swap写法的异常原因
你的__init__方法中默认参数val = [0, 1]是可变的列表类型:
- 实例a初始化时没有传参,
a.val直接指向函数定义时生成的默认列表对象 - 第一种
swap方法是原地修改列表的元素,没有创建新列表,修改的就是这个共享的默认列表对象 - 实例b初始化时同样没有传参,
b.val也指向同一个已经被修改过的默认列表,所以输出为[1, 0]
修改后swap写法正常的原因
修改后的swap方法逻辑是先创建一个全新的列表对象,再把新列表赋值给self.val:
- 执行
a.swap()后,a.val不再指向原来的共享默认列表,而是指向新创建的列表 - 此时共享的默认列表本身没有被修改,后续实例b初始化时拿到的还是初始的
[0, 1],输出符合预期
最佳实践建议
不要直接使用可变类型作为函数默认参数,正确的写法是用None作为占位符,在函数内部初始化可变对象:
class MyClass: def __init__(self, val = None): # 每次无参调用时都会生成新的列表,不会出现共享问题 if val is None: val = [0, 1] self.val = val # 其余方法保持不变
内容的提问来源于stack exchange,提问作者Yelemiz
相关产品推荐
相关产品推荐

