c语言编程笔录

首页 >   > 笔记大全

笔记大全

Python 实现单例模式的五种写法

更新时间:2023-10-07

概述

单例模式是一种经典的设计模式,它主要用于在整个应用程序中创建单一实例的对象。Python中的单例模式主要涉及到Python语言的引用计数机制和模块机制。

方法一:使用模块

Python中模块在程序中只被加载一次,因此可以使用模块来实现单例模式。我们可以在模块中封装一个单例对象,然后在其他模块中引用该模块即可使用该单例对象。


# singleton.py
class SingletonClass:
    def __init__(self):
        self.name = 'SingletonClass'

single_instance = SingletonClass()

# main.py
import singleton

obj1 = singleton.single_instance
obj2 = singleton.single_instance
print(obj1 is obj2)  # output: True

方法二:使用装饰器

装饰器是Python的一个高级特性,它可以在不修改原函数的情况下,添加新的功能。我们可以使用装饰器来实现单例模式。


def singleton(cls):
    instances = {}
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return get_instance

@singleton
class MyClass:
    def __init__(self):
        self.name = 'MyClass'

obj1 = MyClass()
obj2 = MyClass()
print(obj1 is obj2)  # output: True

方法三:使用元类

元类是Python的一个高级特性,它可以动态地创建类。我们可以使用元类来实现单例模式。


class SingletonMeta(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]

class MyClass(metaclass=SingletonMeta):
    def __init__(self):
        self.name = 'MyClass'

obj1 = MyClass()
obj2 = MyClass()
print(obj1 is obj2)  # output: True

方法四:使用类装饰器

除了使用函数装饰器外,我们还可以使用类装饰器来实现单例模式。


class SingletonClass:
    _instances = {}
    def __init__(self, cls):
        self.cls = cls
    def __call__(self, *args, **kwargs):
        if self.cls not in self._instances:
            self._instances[self.cls] = self.cls(*args, **kwargs)
        return self._instances[self.cls]

@SingletonClass
class MyClass:
    def __init__(self):
        self.name = 'MyClass'

obj1 = MyClass()
obj2 = MyClass()
print(obj1 is obj2)  # output: True

方法五:使用__new__方法

Python中的每个类都有一个__new__方法,它是实例化一个对象的第一步。我们可以重写__new__方法来实现单例模式。


class SingletonClass:
    _instance = None
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    def __init__(self):
        self.name = 'SingletonClass'

obj1 = SingletonClass()
obj2 = SingletonClass()
print(obj1 is obj2)  # output: True