Python单例模式(Singleton)的N种实现

单例模式是一种设计模式,确保类只有一个实例,并提供全局访问点。在Python中,可以通过函数装饰器、类装饰器、`__new__`关键字和元类来实现。常见应用场景包括日志文件、应用配置、线程池和数据库连接池等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单例是一种设计模式,应用该模式的类只会生成一个实例。
单例模式保证了在程序的不同位置都可以且仅可以取到同一个对象实例:如果实例不存在,会创建一个实例;如果已存在就会返回这个实例。因为单例是个类,所以你也可以为其提供相应的操作犯法,以便于对这个实例进行管理。
举个例子来说,比如你开发一款游戏软件,游戏中需要有“场景管理器”,这样一种东西,,用来管理游戏场景的切换、资源载入、网络连接等等任务。这个管理器需要多种方法和属性,在代码的很多地方会被调用,且被调用的必须是同一个管理器,否则既容易产生冲突,也会浪费资源。这种情况下,单例模式就是一个很好的实现方法。
以下是实现方法索引:

  • 使用函数装饰器实现单例
  • 使用类装饰器实现单例
  • 使用new关键字实现单例
  • 使用metaclass实现单例

使用函数装饰器实现单例

def singleton(cls):
    _instance = {}

    def inner():
        if cls not in _instance:
            _instance[cls] = cls()
        return _instance[cls]

    return inner


@singleton
class Cls(object):
    def __init__(self):
        pass


cls1 = Cls()
cls2 = Cls()
print(id(cls1) == id(cls2)) # True
# 去掉装饰器为False

在Python中,id关键字可用来查看对象在内存中的存放位置,这里cls1和cls2的id值形同,说明他们指向同一个对象。

使用类装饰器实现单例

class Singleton(object):
    def __init__(self, cls):
        self._cls = cls
        self._instance = {}

    def __call__(self, *args, **kwargs):
        if self._cls not in self._instance:
            self._instance[self._cls] = self._cls()
        return self._instance[self._cls]


@Singleton
class Cls(object):
    def __init__(self):
        pass


cls1 = Cls()
cls2 = Cls()
print(id(cls1) == id(cls2))

使用New关键字实现单例模式

class Single(object):
    _instance = None

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = object.__new__(cls)
        return cls._instance

    def __init__(self):
        pass


single1 = Single()
single2 = Single()
print(id(single1) == id(single2))

使用metaclass实现单例模式

class Singleton(type):
    _instances = {}

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


class Cls4(metaclass=Singleton):
    pass


cls1 = Cls4()
cls2 = Cls4()
print(id(cls1) == id(cls2))

应用场景

(1)资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如日志文件,应用配置。
(2)控制资源的情况下,方便资源之间的互相通信。如线程池等。 1.网站的计数器 2.应用配置 3.多线程池 4.数据库配置,数据库连接池 5.应用程序的日志应用…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值