2014-02-05 41 views
1

快速的問題,當你說del object時,python調用什麼神奇的方法?我知道這不是__del__,它不是__delete__,所以如果有什麼被調用?如果什麼都沒有調用,那麼我如何定製刪除對象時發生的事件?python del語句的魔術方法?


下面的例子看看:

class SingletonError(Exception): 
    pass 

class Singleton(type): 

    def __new__(metacls, name, parents, kwargs): 
     cls = super(Singleton, metacls).__new__(metacls, name, parents, kwargs) 
     cls._instance = None 
     return cls 

    def __call__(cls, *args, **kwargs): 
     if not cls._instance: 
      inst = cls.__new__(cls, *args, **kwargs) 
      inst.__init__(*args, **kwargs) 
      cls._instance = inst 
      return cls._instance 
     else: 
      raise SingletonError("Cannot initialize multiple singletons.") 

class Logger(object, metaclass = Singleton): 

    def __new__(cls, *logging_args, **logging_kwargs): 
     self = super(Logger, cls).__new__(cls) 
     logging_args_dict = {'log%i' % pos : i for pos, i in enumerate(logging_args, 1)} 
     kwargs = dict(logging_args_dict, **logging_kwargs) 
     self.__dict__ = kwargs 
     return self 

log = Logger() 

當我刪除日誌我想它Logger._instance重新設置爲無,這樣你就可以重新初始化單。我該怎麼做?

+9

你不能,因爲del不刪除對象,它會刪除指向對象的* name *。 – BrenBarn

+2

http://docs.python.org/2/reference/datamodel.html#object.__del__ –

+0

好的,我編輯了這個問題以包含我面臨的情況,以及爲什麼我首先提出了這個問題。 – user3002473

回答

2

您可以改用weak reference;因爲所有對Logger()實例的引用都被清除,所以弱引用不會阻止對象被收割。

import gc 
import weakref 

def __call__(cls, *args, **kwargs): 
    gc.collect() # optional, clear existing weak references 
    inst = cls._instance and cls._instance() # de-reference the weakref 
    if inst is None: 
     inst = cls.__new__(cls, *args, **kwargs) 
     inst.__init__(*args, **kwargs) 
     cls._instance = weakref.ref(inst) 
     return inst 
    else: 
     del inst # clear local early 
     raise SingletonError("Cannot initialize multiple singletons.") 

cls._instance現在是一個弱引用對象;你可以調用它來檢索引用的對象,如果它返回None對象已經不存在了,你需要創建一個新對象。

只要考慮到刪除不一定是即時的;一旦最後的常規引用被刪除,垃圾收集需要運行以收穫對象。

gc.collect() call作爲__call__第一行確保任何弱refences在測試之前清理。