2015-07-03 48 views
3

我想實現的字典,會做的是得到插入鑰匙某些檢查,例如請參見下文:的Python 2.6.5 defaultdict覆蓋__setitem__無限遞歸

from collections import defaultdict 

class CheckingDict(defaultdict): 

    def __init__(self, *args, **kwargs): 
     super(CheckingDict, self).__init__(*args, **kwargs) 

    def __setitem__(self, key, value): 
     if not super(CheckingDict, self).__missing__(key): 
      raise ValueError("Key {key} is already present".format(key=key)) 
     else: 
      return defaultdict.__setitem__(self, key, value) 

a = CheckingDict(lambda: None) 
a[1] = 1 

上面代碼中的問題這是給我無限遞歸。所以問題是爲什麼以及如何正確地做到這一點?

我不想使用組合,因爲要獲得defaultdict的所有功能,我需要編寫更多的代碼。

回答

4

這是__missing__這是造成問題,並注意:

  1. 有沒有點定義__init__如果調用父;和
  2. 實際設置項目時,您沒有使用super

的工作實現:

class CheckingDict(defaultdict): 

    def __setitem__(self, key, value): 
     if key in self: 
      raise ValueError("Key {!r} is already present".format(key)) 
     super(CheckingDict, self).__setitem__(key, value) 

那麼,爲什麼叫__missing__呼叫__setitem__,導致遞歸?該方法不只是告訴你key是否丟失;每the documentation(重點煤礦):

如果default_factory不是None,[__missing__]不帶參數的被調用來 給定鍵,這個值被插入 字典用於鍵提供默認值,並返回。

這是__missing__這實際上是把默認值到字典如果密鑰已不存在,這意味着它必須調用__setitem__這樣做。