2009-08-11 52 views
2

日安pythonians,鎖定一個自定義詞典

我希望做一個自定義詞典有兩個主要特點:

  1. 所有按鍵都宣佈創建
  2. 這是不可能添加新鍵或修改當前者(值仍修改)

現在的代碼是這樣的:

class pick(dict): 
    """This will make delicious toffee when finished""" 
    def __init__(self, *args): 
     dict.__init__(self) 
     for arg in args: 
      self[arg] = None 

任何幫助,非常感謝。

UPD:

雖然解決辦法是什麼我一直在尋找有一個問題:

字典調用__setitem__上添加初始化的項目,並沒有找到它引發錯誤的鑰匙。

cupboard = pick('milk') #raises error 

upd1:

都解決了,非常感謝你。

+0

是#2,應該是「這是不可能添加新鍵(現有的仍然是修改)」,「這是不可能添加新鍵或修改現有的」,或「這是不可能添加新鍵或修改當前的值(值仍然可以修改)「? – JAB 2009-08-11 14:35:34

+0

啊!愚蠢的是,我第一次寫這裏有點緊張。它是(值仍然可以修改) – Rince 2009-08-11 14:42:56

回答

12

用您期望的行爲覆蓋__setitem__方法,請撥dict.__setitem__(self, key, value)修改基本字典而不通過您的基本邏輯。

class ImmutableDict(dict): 
    def __setitem__(self, key, value): 
     if key not in self: 
      raise KeyError("Immutable dict") 
     dict.__setitem__(self, key, value) 

d = ImmutableDict(foo=1, bar=2) 
d['foo'] = 3 
print(d) 
d['baz'] = 4 # Raises error 

您還需要重寫dict.update()setdefault()避免此外鍵。可能還有dict.__delitem__(),dict.clear(),dict.pop()dict.popitem(),以避免刪除密鑰。

2

喜歡的東西

class UniqueDict(dict): 
    def __init__(self, *args, **kwargs): 
     dict.__init__(self, *args, **kwargs) 

    def __setitem__(self, name, value): 
     if name not in self: 
      raise KeyError("%s not present") 
     dict.__setitem__(self, name, value) 
2

我建議你使用授權,而不是繼承。 如果你繼承,字典中的所有以前的方法都將被繼承,但它們可能會像你所期望的那樣行事,從而破壞了你對這個類的假設,並且默默地去做。

如果您進行授權,您可以完全控制您提供的方法,並且如果您嘗試在需要未實現的方法的上下文中使用您的詞典,您將會遇到異常,無法快速解決問題。

+0

當您提出一個有趣的觀點時,dict是一個非常透明的類,並且驗證您已經涵蓋了設置鍵的所有可能性並不難。所以我不會推薦代表團。 – 2009-08-11 14:35:05

+0

是的。被繼承燒燬了。現在我非常小心;) – 2009-08-11 16:14:49