Python 中的单例设计模式

Manav Narula 2023年1月30日 2022年5月18日
  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 中创建模块。一个只包含函数的模块可以作为单例,这是因为它将所有这些函数绑定到模块。

Author: 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