Python:自定义类与嵌套defaultdict一起使用

时间:2018-07-25 15:42:50

标签: python defaultdict shallow-copy

你好,我有这两个班

class BaseCounter(object): 
  def __init__(self):
    print ("BaseCounter init = ")
    self._counter = 0

  def increment(self, count=1):       
    self._counter += count

  def items(self):
    return self._counter


class DictCounter(object):
  def __init__(self, dict_class):
    self._counter = defaultdict(lambda: dict_class)

  def increment(self, key, value, *args, **kwargs):
    print (key, value, args, kwargs)
    self._counter[key].increment(value, *args, **kwargs)

  def items(self):
    result = []
    for key, counter in self._counter.items():
        result.append((key, counter.items()))
    return result

我正在尝试创建类似这样的东西:

y = DictCounter(DictCounter(DictCounter(BaseCounter())))
y.increment(10,1,2,3)
y.increment(10,1,2,3)
y.increment(10,1,3,3)
y.increment(10,2,2,3)

导致

10 1 2 12
10 1 3 12
10 2 2 12
10 2 3 12

但我期望

10 1 2 6
10 1 3 3
10 2 2 3

它应该模拟,并且正常工作

defaultdict(defaultdict(defaultdict(int))) "with counter at the end"

但我对此行为感到困惑(我认为浅拷贝或带有引用的内容会出现问题)

有什么主意吗?

1 个答案:

答案 0 :(得分:0)

正如马丁·彼得斯(Martijn Pieters)所说。问题在于每个新键都引用相同的对象(dict_class)。所以代替这个:

class DictCounter(object):
   def __init__(self, dict_class):
      self._counter = defaultdict(lambda: dict_class)

 ....

DictCounter(DictCounter(DictCounter(BaseCounter())))

执行此操作:

class DictCounter(object):
   def __init__(self, dict_class):
      self._counter = defaultdict(dict_class)

 ....

DictCounter(lambda: DictCounter(lambda: DictCounter(lambda: BaseCounter())))

我正试图在my blog上进行更多描述。