Python 单例模式

lyjin 2024-01-24

Python使用单例模式时,可以创建一个Singleton类,所有继承Singleton的子类,都为单例模式

  1. class Singleton(abc.ABCMeta, type):
  2. """
  3. Singleton metaclass for ensuring only one instance of a class.
  4. """
  5. _instances = {}
  6. def __call__(cls, *args, **kwargs):
  7. """Call method for the singleton metaclass."""
  8. if cls not in cls._instances:
  9. cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
  10. return cls._instances[cls]

这个 Singleton 类是一个元类(metaclass),用于实现单例模式。在Python中,元类是用于创建类的“类”。单例模式确保一个类只有一个实例,并提供全局访问点到这个实例。现在,让我们逐步详细解释这个 Singleton 元类的工作原理:

类定义

  1. class Singleton(abc.ABCMeta, type):
  2. ...
  • 这里定义了一个名为 Singleton 的类,它继承自 abc.ABCMetatype
  • abc.ABCMeta 是一个内建的元类,用于创建抽象基类(ABCs)。
  • type 是Python中所有类的默认元类。在Python中,类也是对象,type 是用来创建这些类对象的类。
  • 通过继承 abc.ABCMetaSingleton 支持创建抽象基类,同时它也是一个元类,因为它继承了 type

类变量

  1. _instances = {}
  • _instances 是一个类变量,用字典来存储每个类的唯一实例。
  • 键是类cls,值是该类的单例实例。

__call__ 方法

  1. def __call__(cls, *args, **kwargs):
  2. ...
  • __call__ 方法在元类中被定义,当类(它是由这个元类创建的)被“调用”以实例化一个新对象时会被触发。
  • cls 参数表示当前正在被实例化的类。
  • args 和 *kwargs 用于接收传递给实例的参数。

创建或返回单例实例

  1. if cls not in cls._instances:
  2. cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
  3. return cls._instances[cls]
  • 这段代码检查 _instances 字典中是否已经存在针对特定 cls 的实例。
  • 如果不存在(即这个类的实例还没有被创建),它将调用父类(实际上是 type)的 call 方法来创建一个实例,并将其存储在 _instances[cls] 中。
  • 如果这个类的实例已经存在,它直接返回这个实例。
  • 这确保了无论何时调用该类(即使是传递不同的参数),都只创建一个实例,并且总是返回同一个实例。

使用示例

  1. class MyClass(metaclass=Singleton):
  2. pass
  3. # 每次创建 MyClass 的实例时,都会得到相同的对象
  4. instance1 = MyClass()
  5. instance2 = MyClass()
  6. assert instance1 is instance2 # 这个断言将会通过,因为 instance1 和 instance2 是同一个对象

总之,这个 Singleton 元类是一个实现单例模式的高级工具。当用它作为元类创建其他类时,这些类将自动成为单例,确保每个类只有一个实例存在。

没有评论
请登陆后评论
新建评论
移除
关闭
提交