【问题标题】:Creating Singletons - How are the instances saved创建单例 - 如何保存实例
【发布时间】:2020-06-09 15:37:12
【问题描述】:

当我学习如何在 Python 中创建单例时,我们大多数人第一次遇到这种装饰器:

def singleton(class_):
    instances = {}
    def getinstance(*args, **kwargs):
        if class_ not in instances:
            instances[class_] = class_(*args, **kwargs)
        return instances[class_]
    return getinstance

@singleton
class MyClass(BaseClass):
    pass

虽然这个装饰器的工作方式非常直观,但让我想知道的是,当我们在“MyClass”中创建第二个对象时,这个装饰器如何检查是否已经创建了一个对象。

在“单例”的定义中,Python 检查“实例”字典。但是,它是一个局部变量:它不应该在函数运行时被销毁吗?因此,if class_ not in instances 条件不应该始终为 True 吗?

由于我知道这个语法有效,所以我一直按原样使用它,但这让我觉得我还没有完全理解局部变量。

【问题讨论】:

  • instancessingleton 内部是局部的,但是在getinstance闭包 中,所以还是有对函数的引用。
  • @jonrsharpe 所以仍然有对 {instances} 的引用,因为 {singleton} 仍然是“开放的”?

标签: python syntax singleton decorator local-variables


【解决方案1】:

getinstanceinstancesclass_闭包。发生的情况是MyClass 不是对class 对象的引用,而是对函数getinstance 的引用。在这两个名称超出范围后,该函数保留对instances 引用的dictclass_ 引用的类的引用。你可以自己看看:

>>> type(MyClass)
<class 'function'>
>>> MyClass.__closure__[0]
<cell at 0x107877d38: type object at 0x7fe0dcc264c8>
>>> MyClass.__closure__[1]
<cell at 0x107877d68: dict object at 0x107843ab0>

__closure__ 元组的第一个元素是对原始类的引用;第二个元素是对实例缓存的引用。

【讨论】:

    猜你喜欢
    • 2017-05-06
    • 2010-11-12
    • 2015-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多