几天前,我遇到了一个与此问题相关的讨厌错误:当我的类的构造函数有一个空字典的默认参数时,该类的所有实例都指向同一个字典。这是一个例子:
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类中),它会为每个对象创建一个新的引用。当字典初始化为默认对象时,即使它被初始化为空字典,所有对象都指向同一字典。
有人可以阐明这种行为,并解释更多关于它的内部运作方式吗?
由于
答案 0 :(得分:3)
执行函数定义时,将评估默认参数值。这意味着在定义函数时,表达式将被计算一次,并且每次调用都使用相同的“预先计算”值。
定义函数时,会创建一个空字典,并绑定到函数对象。作业陈述
self.D = d
指定成员变量指向定义函数时创建的实例。修改该字典将修改绑定为默认值的实例。
可能实现目标的替代定义如下:
def __init__(self, d=None):
if d is None:
self.D = {}
else:
self.D = d