我定义了这个单例元类:
class Singleton(type):
"""Metaclass which implements the singleton pattern"""
_instances = {}
def __call__(self, *args, **kwargs):
if self not in self._instances:
self._instances[self] = super(Singleton, self).__call__(*args, **kwargs)
return self._instances[self]
现在,我想测试一下是否一切正常。这是我尝试过的:
- 我创建了同一类的两个对象(具有
Singleton
作为元类的类)- 它们的id()
匹配 - 我创建了一个对象并将其分配给第二个变量 - 它们的
id()
匹配 - 我导入了
copy
模块并使用copy.copy()
复制了第一个对象 - 它们的id()
现在不匹配
我想知道为什么复制的对象的 id 与原始对象不匹配。既然是单例,那两个对象不应该有相同的id吗?
最佳答案
copy
模块不创建一个新实例;相反,它创建一个空类,并在该对象上重新分配 __class__
以专门避免 __new__
或 __init__
方法原来的。
您需要提供一个自定义的 __copy__
钩子(Hook)来返回未更改的实例:
class Singleton(type):
"""Metaclass which implements the singleton pattern"""
_instances = {}
def __call__(self, *args, **kwargs):
if self not in self._instances:
self._instances[self] = super(Singleton, self).__call__(*args, **kwargs)
return self._instances[self]
def __copy__(cls, instance):
return instance
copy
直接在类上查找__copy__
方法;它是在 元类 上找到的,在该类上查找 __copy__
将返回一个绑定(bind)方法,并且 copy
(期望未绑定(bind)方法)通过在实例中明确。这意味着将有两个 参数传递给__copy__
;第一个是类(元类的实例),第二个是该类的实例(传统方法中的 self
)。
不幸的是,__deepcopy__
是在实例上查找的,但未找到元类方法。
关于python - Python 中的单例对象和复制模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18870851/