Python垃圾收集和单例类

2024-06-26 11:23:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个单例类,我不明白Python垃圾收集器是如何不删除实例的

我正在使用-from singleton_decorator导入singleton

我的班级示例:

from singleton_decorator import singleton

@singleton
class FilesRetriever:

    def __init__(self, testing_mode: bool = False):
        self.testing_mode = testing_mode

测试示例:

def test_singletone(self):
    FilesRetriever(testing_mode=True)
    mode = FilesRetriever().testing_mode
    print("mode 1:" + str(mode))
    mode = FilesRetriever().testing_mode
    print("mode 2:" + str(mode))
    count_before = gc.get_count()
    gc.collect()
    count_after = gc.get_count()
    mode = FilesRetriever().testing_mode
    print("mode 3:" + str(mode))
    print("count_before:" + str(count_before))
    print("count_after:" + str(count_after))   

测试输出:

mode 1:True
mode 2:True
mode 3:True
count_before:(306, 10, 5)
count_after:(0, 0, 0)

我希望在垃圾收集器自动运行或在测试中运行它之后,_SingletonWrapper(decorator实现中的类)的实例将被删除,因为没有任何对象指向它。然后“print”(“mode 3:“+str(mode))”的值将为False,因为这是默认值(实例已重新创建)


Tags: 实例selftruemodecountdecoratortestinggc
1条回答
网友
1楼 · 发布于 2024-06-26 11:23:16

因此,代码和垃圾收集工作正常。请看您所指的单例装饰器的代码decorator

仅仅因为您调用了gc.collect(),并且您的代码没有在某处保存引用,并不意味着其他代码没有

在decorator中,它创建一个实例,然后将该实例存储在decorator中的一个变量中。因此,即使您收集了与代码相关的数据。他们的代码仍然持有对该实例的引用,因此无法收集该实例

这是单身汉的预期行为,因为这是它的全部目的。是将实例存储在可以检索和使用的地方,而不是每次都创建一个新实例。因此,除非需要替换该实例,否则您不会希望该实例被丢弃

回答您的评论

  1. 不,您没有将实例获取到_SingletonWrapper。当您编写FileRetriever()时,您实际上正在调用_SingletonWrapper实例的__call__方法。使用@singleton()返回实例而不是类对象时

  2. 同样,在代码中,您不将其存储在任何地方并不意味着它不存储在其他地方。当您定义一个类时,您所做的在某种意义上是在模块的全局范围内,它正在创建一个保存该类定义的变量。所以在全局范围内的代码中,它是这样的

FileRetriever = (class:
    def __init__(self):
        blahblahblah

现在,类定义存储在变量调用FileRetriever

现在您使用的是一个装饰器,看起来是基于单个装饰器中的代码

FileRetriever = _SingletonWrapper(class: blahblah)

现在您可以看到类被包装并存储在变量FileRetriever中。 现在,在运行FileRetriever()时调用_SingletonWrapper.__call__()。 因为__call__是一个实例方法。它可以保存对您的原始类和您声明的类的实例的引用,因此即使您删除了对该类的所有引用,该代码仍然保留该引用

如果你真的想删除所有关于你是单身汉的引用,我不知道你为什么会这么做。您需要删除对包装器的所有引用以及您的类。因此FileRetriever = None之类的内容可能会导致gc收集它。但在这个过程中,您将失去原始的类定义

相关问题 更多 >