Python使用单例模式时,可以创建一个Singleton类,所有继承Singleton的子类,都为单例模式
class Singleton(abc.ABCMeta, type):
"""
Singleton metaclass for ensuring only one instance of a class.
"""
_instances = {}
def __call__(cls, *args, **kwargs):
"""Call method for the singleton metaclass."""
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
这个 Singleton 类是一个元类(metaclass),用于实现单例模式。在Python中,元类是用于创建类的“类”。单例模式确保一个类只有一个实例,并提供全局访问点到这个实例。现在,让我们逐步详细解释这个 Singleton 元类的工作原理:
类定义
class Singleton(abc.ABCMeta, type):
...
- 这里定义了一个名为 Singleton 的类,它继承自 abc.ABCMeta 和 type。
- abc.ABCMeta 是一个内建的元类,用于创建抽象基类(ABCs)。
- type 是Python中所有类的默认元类。在Python中,类也是对象,type 是用来创建这些类对象的类。
- 通过继承 abc.ABCMeta,Singleton 支持创建抽象基类,同时它也是一个元类,因为它继承了 type。
类变量
_instances = {}
- _instances 是一个类变量,用字典来存储每个类的唯一实例。
- 键是类cls,值是该类的单例实例。
__call__ 方法
def __call__(cls, *args, **kwargs):
...
- __call__ 方法在元类中被定义,当类(它是由这个元类创建的)被“调用”以实例化一个新对象时会被触发。
- cls 参数表示当前正在被实例化的类。
- args 和 *kwargs 用于接收传递给实例的参数。
创建或返回单例实例
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
- 这段代码检查 _instances 字典中是否已经存在针对特定 cls 的实例。
- 如果不存在(即这个类的实例还没有被创建),它将调用父类(实际上是 type)的 call 方法来创建一个实例,并将其存储在 _instances[cls] 中。
- 如果这个类的实例已经存在,它直接返回这个实例。
- 这确保了无论何时调用该类(即使是传递不同的参数),都只创建一个实例,并且总是返回同一个实例。
使用示例
class MyClass(metaclass=Singleton):
pass
# 每次创建 MyClass 的实例时,都会得到相同的对象
instance1 = MyClass()
instance2 = MyClass()
assert instance1 is instance2 # 这个断言将会通过,因为 instance1 和 instance2 是同一个对象
总之,这个 Singleton 元类是一个实现单例模式的高级工具。当用它作为元类创建其他类时,这些类将自动成为单例,确保每个类只有一个实例存在。