2014-02-16 57 views
0

中的項目值我試圖創建一個類來處理我在Python中的自定義文件類型。我希望它的行爲完全像字典,所以我擴展了內置的dict類,添加了open(實際上是__init__)並保存了函數。結構如下:覆蓋Python中的__setitem__ dict子類不能用於設置

{ 
    'A': [ 
    [1, 'Doe', 'John', '49396928593', '0', '23', '20'], 
    [2, 'Smith', 'Mark', '05926836832', '0', '6', '14'], 
    ], 
    'B': [ 
    # and so on 
    ] 
} 

所以它基本上是一個列表清單的字典。

現在我想要有一個類變量,changed wolud會自動設置爲True當對象發生任何變化時。顯然,我的類的__setitem__只有當直接在字典中的項目發生更改時纔會觸發。有沒有辦法來抓住我的字典的子項目的任何改變?

這裏是我的代碼:

import zlib 
import json 

class MRK(dict): 

    def __init__(self, path): 
     self.path = path 
     self.changed = False 

     fp = open(path, "r") 
     compressed = fp.read() 
     fp.close()  
     json_data = zlib.decompress(compressed) 
     data = json.loads(json_data) 
     super(MRK, self).__init__(data) 

    def __setitem__(self, key, value): 
     print "!" 
     self.changed = True 
     super(MRK, self).__setitem__(key, value) 

    def save(self): 
     json_data = json.dumps(self) 

     compressed = zlib.compress(json_data) 
     fp = open(self.path, "w") 
     fp.write(compressed) 
     fp.close() 


f = MRK('dane.mrk') 

for c in f: 
    print c 

    for std in f[c]: 
     if std[1]=='Smith': 
      std[1] = 'Brown' 
     print std 

print f.changed # outputs False 

f.save() 

回答

0

不,沒有;您必須爲這些對象使用自定義列表對象,並將「已更改」標誌傳播到父字典或使用中央對象來跟蹤更改。

一旦你從字典中檢索一個對象,字典本身與它無關;例如,您可以將該對象存儲在單獨的引用中,並在不涉及原始字典的情況下傳遞該對象。

的另一種選擇是總是需要的對象進行明確的重新設置:

lstobj = yourdict['A'] 
lstobj[1][1] = 'Sue' 
# explicit set to notify `yourdict` 
yourdict['A'] = lstobj 
+0

感謝了迅速的回答。現在我想知道如果我手動維護這個標誌是否真的值得付出努力。 –

+0

您可以查看ZODB持久性包,因爲它們也必須跟蹤更改的對象。 'PersistentMapping'和'PersistentList'是自定義的實現,它會在'self'上設置一個改變的標誌,然後一箇中央管理器會將改變提交給它們所註冊的ZODB。 –