所有对象实例的默认初始值设定项都指向相同的数据?

时间:2014-02-26 05:09:32

标签: python dictionary mutable

几天前,我遇到了一个与此问题相关的讨厌错误:当我的类的构造函数有一个空字典的默认参数时,该类的所有实例都指向同一个字典。这是一个例子:

class A:
    def __init__(self, d={}):
        self.D = d

class B:
    def __init__(self):
        self.D = {}

a1 = A()
a2 = A()
b1 = B()
b2 = B()

a1.D.update({'Akey':'Avalue'})
print("Printing a1 dict: ", a1.D)
print("Printing a2 dict: ", a2.D)

b1.D.update({'Bkey':'Bvalue'})
print("Printing b1 dict: ", b1.D)
print("Printing b2 dict: ", b2.D)

输出继电器:

Printing a1 dict:  {'Akey': 'Avalue'}
Printing a2 dict:  {'Akey': 'Avalue'}
Printing b1 dict:  {'Bkey': 'Bvalue'}
Printing b2 dict:  {}

我怀疑当在构造函数内部初始化字典时(如在B类中),它会为每个对象创建一个新的引用。当字典初始化为默认对象时,即使它被初始化为空字典,所有对象都指向同一字典。

有人可以阐明这种行为,并解释更多关于它的内部运作方式吗?

由于

1 个答案:

答案 0 :(得分:3)

来自Python Language Reference

  

执行函数定义时,将评估默认参数值。这意味着在定义函数时,表达式将被计算一次,并且每次调用都使用相同的“预先计算”值。

定义函数时,会创建一个空字典,并绑定到函数对象。作业陈述

self.D = d

指定成员变量指向定义函数时创建的实例。修改该字典将修改绑定为默认值的实例。

可能实现目标的替代定义如下:

def __init__(self, d=None):
    if d is None:
        self.D = {}
    else:
        self.D = d