2014-02-05 6 views
1

빠른 질문, del object라고 말하면 파이썬이 호출하는 마법 방법은 무엇입니까? 나는 그것이 __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을 반환하면 객체가 사라지고 새 객체를 만들어야합니다.

삭제가 반드시 즉각적인 것은 아니라는 점을 고려하십시오. 마지막 일반 참조가 제거되면 오브젝트를 확보하기 위해 가비지 콜렉션을 실행해야합니다.

__call__의 첫 번째 줄에있는 gc.collect() call은 약한 지문이 테스트 전에 정리되도록합니다.