2016-07-07 64 views
0

我想寫與單例模式類使用泡菜/字典提供一些持久性數據存儲:python3單例模式與「用」的聲明

@singleton 
class Pdb: 
    def __init__(self): 
     self.cache = None 
     self.dirty = False 
     try: 
      with open("data.pck","rb") as fp: 
       self.cache = pickle.load(fp) 
     except FileNotFoundError: 
      pass 
     except pickle.PickleError: 
      pass 

     if self.cache is None: 
      self.cache = {} 

    def flush(self): 
     if self.dirty: 
      try: 
       with open("data.pck","wb") as fp: 
        pickle.dump(self.cache,fp,protocol=4) 
      except pickle.PickleError: 
       pass 
      else: 
       self.dirty = False 

    def __del__(self): # PROBLEM HERE 
     self.flush() 

當我使用python 2,我可以做到這一點覆蓋__del__。但它似乎不正確的python 3.我該怎麼做?

如果我通過做「與」語句,我需要將實例傳遞給每一個我稱之爲功能:

def func1(db): 
    db.set(...) 
    func3(db,x1,x2,...) 

with Pdb() as db: 
    func1(db) 
    func2(db) 

它是複雜的。 「有」陳述有沒有一種Python方法來做全球範圍?

回答

1

如果我通過做「與」語句,我需要將實例傳遞給每一個我稱之爲功能:

不,你不知道。只需使用你的單身:

# global 
db = Pdb() 

# any other context 
with db: 

所有這一切需要的是表達產生上下文管理。使用__enter____exit__方法引用單例對象將滿足該要求。如上所述,您甚至可以忽略返回值__enter__。全球將仍然可用於所有功能,唯一的變化是__enter____exit__將在適當的位置被調用。

請注意,即使在Python 2中,您也應該調用而不是依賴__del__。而在CPython實現中,在循環引用之外,在Python 2和3之間調用__del__時的規則沒有發生變化。

+0

是的。我可以這樣做。但是我每次更新Pdb()時都會調用flush()。它花費我的CPU時間,我希望它在代碼終止時自動刷新到磁盤。 – wonghang

+1

@wonghang:那麼爲什麼不在頂級函數中使用'with db:'* *? –

+0

沒錯。你可能是對的。謝謝。 – wonghang