似乎沒有內建的方式來獲得字典的視圖。最簡單的解決方法似乎是Jochen的方法。我適應了他的代碼稍微讓它爲我的目的工作:在各方面
from collections import MutableMapping
class DictView(MutableMapping):
def __init__(self, source, valid_keys):
self.source, self.valid_keys = source, valid_keys
def __getitem__(self, key):
if key in self.valid_keys:
return self.source[key]
else:
raise KeyError(key)
def __len__(self):
return len(self.valid_keys)
def __iter__(self):
for key in self.valid_keys:
yield key
def __setitem__(self, key, value):
if key in self.valid_keys:
self.source[key] = value
else:
raise KeyError(key)
def __delitem__(self, key):
self.valid_keys.remove(key)
d = dict(a=1, b=2, c=3)
valid_keys = ['a', 'c']
d2 = DictView(d, valid_keys)
d2['a'] = -1 # overwrite element 'a' in source dictionary
print d # prints {'a': -1, 'c': 3, 'b': 2}
所以d2
行爲就像一本字典,除了印刷,由於不同__repr__()
方法。繼承dict
得到__repr__()
將需要重新實現每一種方法,如collections.OrderedDict
所做的那樣。如果只需要只讀視圖,則可以繼承collections.Mapping
並保存__setitem__()
和__delitem__()
的實現。我發現DictView
用於從self.__dict__
中選擇參數並將它們以緊湊形式傳遞。
我建議的「不可改變的觀點」在一本字典正是你與你的示例代碼獲取...因爲缺席使得字典的單獨副本,我不知道你將如何讓「不可變的」部分工作。 – larsks 2012-02-17 14:07:46
@larsks:它可能根本不支持分配。 – Marcin 2012-02-17 14:16:36
@larsks:我認爲,通過「不可變視圖」,OP意味着視圖對象本身沒有方法來改變字典(例如pop),並且對視圖中包含的字典的任何更改都立即可見。當然,它在「深層」意義上並不是不可變的 - 也就是說,如果您執行my_view [some_key] .append(12),那麼當然對應於12的值將被修改。 – 2012-02-17 14:17:58