Python类中字典默认参数初始化导致实例共享问题咨询
Python类默认参数字典共享问题的原因解析
核心现象回顾
在类的__init__方法中:
- 把
aDic={}设为默认参数并赋值给实例属性时:传入自定义字典的实例(如obj1、obj2),各自的aDic相互独立;不传字典的实例(如obj3、obj4),所有实例的aDic共享同一个对象,修改其中一个会影响其他实例。 - 但在
__init__内直接创建空字典的anotherDic、通过kwargs.get初始化的kwDic,每个实例的对应属性都是独立的,不存在共享问题。
问题根源
这是Python默认参数的创建时机特性导致的:
- 默认参数在函数定义时创建:Python的函数(包括类的
__init__方法)的默认参数,是在函数被定义的那一刻就创建完成,而不是每次调用函数(实例化类)时重新生成。所以aDic={}这个空字典,在类定义阶段就已经是一个固定的内存对象,地址不会变。 - 不传参数时复用默认对象:当实例化类时不传入
aDic参数,所有这类实例都会直接引用这个预先创建好的默认字典对象,因此它们的self.aDic指向同一个内存地址,修改其中一个实例的aDic,本质是修改同一个字典对象,其他实例自然会看到变化。 - 传入参数时绑定新对象:如果传入自定义的字典,实例的
self.aDic会指向你传入的那个新字典对象,和其他实例的字典没有关联,所以相互独立。
为什么另外两种方式没问题?
__init__内直接创建空字典:self.anotherDic = {}是在每次调用__init__(即每次实例化)时,都会新建一个全新的空字典对象,每个实例拿到的都是自己独有的字典,自然不会共享。kwargs.get('kwDic', {}):每次调用__init__时,如果kwargs里没有kwDic,get方法会临时创建一个新的空字典返回给实例,每个实例的kwDic都是新对象,不存在共享。
代码示例验证
class Test: def __init__(self, aDic={}, **kwargs): self.aDic = aDic self.anotherDic = {} self.kwDic = kwargs.get('kwDic', {}) # 传入自定义字典的实例 obj1 = Test({'name': 'obj1'}) obj2 = Test({'name': 'obj2'}) print(id(obj1.aDic), id(obj2.aDic)) # 地址不同,相互独立 # 不传入字典的实例 obj3 = Test() obj4 = Test() print(id(obj3.aDic), id(obj4.aDic)) # 地址相同,共享同一个字典 obj3.aDic['key'] = 'test' print(obj4.aDic) # 输出 {'key': 'test'},验证共享特性 # 查看anotherDic的地址 print(id(obj3.anotherDic), id(obj4.anotherDic)) # 地址不同,各自独立
内容的提问来源于stack exchange,提问作者PalomaLVP
相关产品推荐
相关产品推荐

