Python 中的单例设计模式

Manav Narula 2023年1月30日
  1. 在 Python 中使用装饰器实现单例设计模式
  2. 在 Python 中使用基类实现单例设计模式
  3. 在 Python 中使用元类实现单例设计模式
  4. 在 Python 中使用模块实现单例设计模式
Python 中的单例设计模式

设计模式可以代表一些代码来解决问题。单例就是这样一种设计模式,我们可以在 Python 中创建一个类的不同对象。

此模式仅限制给定类的一个对象。有几种方法可以在 Python 中模拟这种模式。

在 Python 中使用装饰器实现单例设计模式

Python 中的装饰器是可以将其他函数和对象作为参数并修改其行为的函数。要使用装饰器,我们使用 @ 符号。

我们可以使用它们来实现单例设计模式。

看下面的例子,

def singleton_dec(class_):
    instances = {}

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

    return getinstance


@singleton_dec
class Sample:
    def __init__(self):
        print("Object created.")


x = Sample()
y = Sample()
print(x, y)

输出:

Object created.
<__main__.Sample object at 0x0000015E72D3CA48> <__main__.Sample object at 0x0000015E72D3CA48>

在上面的例子中,我们创建了一个装饰器,它将整个类作为参数。这个装饰器允许我们实现单例对象,这可以通过 xy 的位置来确认。

为 Singleton 使用装饰器的缺点是最终的类 Sample 变成了一个函数,所以我们不能使用类方法。

在 Python 中使用基类实现单例设计模式

基类是一个特殊的类,我们可以从中派生出其他类。没有创建此基类的实例。

我们可以使用基类为 Python 中的 Singleton 提供结构。

例如,

class Singleton_base(object):
    _instance = None

    def __new__(class_, *args, **kwargs):
        if not isinstance(class_._instance, class_):
            class_._instance = object.__new__(class_, *args, **kwargs)
        return class_._instance


class Sample1(Singleton_base):
    def __init__(self):
        print("Object created.")


x = Sample1()
y = Sample1()
print(x, y)

输出:

Object created.
Object created.
<__main__.Sample object at 0x0000015E72D3F388> <__main__.Sample object at 0x0000015E72D3F388>

这是一种有效的方法;但是,当由于多重继承而涉及多个类时,可能会出现错误。

在 Python 中使用元类实现单例设计模式

元类是 Python 中一个非常有趣的特性,因为它可以定义类对象的行为。我们可以说它是一个类为一个类。

在 Python 2 中,我们在类中添加了 __metaclass__ 属性。在 Python 3 中,我们可以将其作为参数添加到类中。

我们可以利用这个特性在 Python 中实现 Singleton 设计。

例如,

class Singleton_meta(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton_meta, cls).__call__(*args, **kwargs)
        return cls._instances[cls]


class Sample(metaclass=Singleton_meta):
    def __init__(self):
        print("Object created.")


x = Sample()
y = Sample()
print(x, y)

输出:

Object created.
<__main__.Sample object at 0x0000015E72D3FF88> <__main__.Sample object at 0x0000015E72D3FF88>

这是元类的恰当应用,实现了自动继承。

在 Python 中使用模块实现单例设计模式

在 Python 中单例的最简单和最基本的实现可能是使用模块。

我们知道我们可以在 Python 中创建模块。一个只包含函数的模块可以作为单例,这是因为它将所有这些函数绑定到模块。

作者: Manav Narula
Manav Narula avatar Manav Narula avatar

Manav is a IT Professional who has a lot of experience as a core developer in many live projects. He is an avid learner who enjoys learning new things and sharing his findings whenever possible.

LinkedIn