当defaultdict被配置为实例化一个类时,如果该类具有默认参数,则行为会有所不同。
例如,这就是预期行为:
from typing import List
from collections import defaultdict
class Test:
def __init__(self):
self.values = []
tests = defaultdict(Test)
tests['a'].values.append(1)
tests['b'].values.append(2)
print([f"{id}: {t.values}" for id, t in tests.items()]) #--> ['a: [1]', 'b: [2]']
现在,当类具有默认值时,所有对象共享相同的引用:
class Test:
def __init__(self, values = []):
self.values = values
tests = defaultdict(Test)
tests['a'].values.append(1)
tests['b'].values.append(2)
print([f"{id}: {t.values}" for id, t in tests.items()]) #--> ['a: [1, 2]', 'b: [1, 2]']
只有当参数是参考时才会发生这种情况,例如:
class Test:
def __init__(self, values = 0):
self.values = values
tests = defaultdict(Test)
tests['a'].values += 1
tests['b'].values += 1
print([f"{id}: {t.values}" for id, t in tests.items()]) #--> ['a: 1', 'b: 1']
为什么?
之所以会发生这种情况,是因为在定义函数时只计算一次默认值,而不是每次调用它。
https://docs.python-guide.org/writing/gotchas/#mutable-默认参数
为了澄清,python中的所有var都是引用。只是它们所指的有些东西是可变的,有些则不然。