python - 创建单例 - 如何保存实例
问题描述
当我在学习如何在 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
条件不应该总是为真吗?
因为我知道这种语法有效,所以我一直按原样使用它,但这让我觉得我还没有完全理解局部变量。
解决方案
getinstance
是和的闭包。发生的事情不是对对象的引用,而是对函数的引用。在这两个名称超出范围之后,该函数保留对被引用的引用和引用的类的引用。你可以自己看看:instances
class_
MyClass
class
getinstance
dict
instances
class_
>>> 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__
是对原始类的引用;第二个元素是对实例缓存的引用。
推荐阅读
- typescript - 尝试将 tsconfig 作为 json 对象加载
- css - 我想在悬停时向表格行添加新选项
- c - 为什么 execvp() 中的 wc 命令从我的 shell 中的管道获取输入时返回错误的结果?
- oracle - 查询行左连接不匹配 ansi 连接等价行
- python - 如何正确读取和编码通过烧瓶发送的文本?
- reactjs - 在 React.js 中使用自定义图标
- reactjs - 如何在 React 中处理静态文件的状态码
- java - 在 Wildfly v.21(与 v.22 相同)第二个集群节点启动时,具有 NON_XA 事务的复制缓存无法同步缓存数据
- javascript - 从另一个方向导入整个 SVG 图像文件夹
- c# - 未找到本地 IP