简体   繁体   English

python del语句的魔术方法?

[英]Magic method for python del statement?

Quick question, what is the magic method python calls when you say del object ? 快速问题,当您说del object时python调用魔术方法是什么? I know it's not __del__ and it isn't __delete__ , so what gets called if anything? 我知道这不是__del__ ,它不__delete__ ,所以如果有什么东西被调用? If nothing is called, then how can I customize the events that occur when you delete an object? 如果什么也没叫,那么我该如何自定义删除对象时发生的事件?


Take a look at the following example: 看下面的例子:

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()

When I delete log I would like it to set Logger._instance to None again, so you can reinitialize the singleton. 当我删除日志时,我希望它再次将Logger._instance设置为None,以便您可以重新初始化单例。 How might I do this? 我该怎么办?

You could use a weak reference instead; 您可以改用弱引用 as all references to the Logger() instances are cleaned up, the weak reference won't prevent the object from being reaped. 由于清除了对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 is now a weak reference object; cls._instance现在是一个弱引用对象; you call it to retrieve the referenced object, and if it returns None the object is gone and you'll need to create a new one. 您调用它来检索引用的对象,如果返回None该对象消失了,您需要创建一个新对象。

Just take into account that the deletion is not necessarily going to be instantaneous; 只需考虑到删除并不一定要是瞬时的。 garbage collection needs to run to reap the object once the last regular reference has been removed. 一旦删除了最后一个常规引用​​,便需要运行垃圾回收以收割该对象。

The gc.collect() call as the first line in the __call__ ensures that any weak refences are cleaned up before testing. 作为__call__第一行的gc.collect()调用可确保在测试之前清除所有弱引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM