单例模式介绍及python实现

简介

在众多设计模式中。对于同一个类,始终提供一个对象,保证提供的对象只有一个,适用于需要频繁进行初始化操作 例如单个数据库的频繁读写操作、多线程操作同一个文件时也需要保证是同一个实例。

1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。

单例模式的python实现

装饰器

使用类变量,一个字典存储唯一的一个实例化对象,当字典为空时则代表对象为空,创建一个对象,否则直接返回字典中的实例化对象。

from functools import wraps


def singleton(cls):
    instance = {}

    @wraps(cls)
    def inner(*args, **kwargs):
        if cls not in instance:
            instance[cls] = cls(*args, **kwargs)
        return instance[cls]

    return inner


@singleton
class Test(object):
    def __init__(self) -> None:
        pass


t1 = Test()
print(id(t1))
t2 = Test()
print(id(t2))
print(t1 == t2)

1461434937120
1461434937120
True

使用基类

由于实例化对象的动作归根结带底是__new__方法返回实例化对象,__init__只是返回__new__的结构,因此重写__new__方法即可,需要注意的是__new__是类方法。

class Singleon(object):
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, "_instance"):
            cls._instance = super(Singleon, cls).__new__(cls, *args, **kwargs)
        return cls._instance


class Test(Singleon):
    def __init__(self) -> None:
        super().__init__()


t1 = Test()
print(id(t1))
t2 = Test()
print(id(t2))
print(t1 == t2)
1751642104896
1751642104896
True

使用元类

由于type是所有类的默认元类,且当类()会调用type的__call__方法,因此只需要重写type的__call__方法即可

from typing import Any


class Singleon(type):
    def __call__(cls, *args: Any, **kwargs: Any) -> Any:
        if not hasattr(cls, "_instance"):
            cls._instance = super().__call__(*args, **kwargs)
        return cls._instance


class Test(metaclass=Singleon):
    def __init__(self) -> None:
        pass


t1 = Test()
print(id(t1))
t2 = Test()
print(id(t2))
print(t1 == t2)
posted @ 2022-08-01 16:18  形同陌路love  阅读(55)  评论(0编辑  收藏  举报