Loading

python单例模式的两种方式

一、通过 __new__ 方法实现

1.示例

class A():
    _instance = None
    def __init__(self, x) -> None:
        self.a = [x]
    def __new__(cls, *args, **kargs):
        if cls._instance is None:
            cls._instance = super(A, cls).__new__(cls)
        return cls._instance

a = A(1)
a.a.append(2)
print(a.a)
b = A(1)

print(id(a)==id(b))
print(a.a)

2.打印结果

[1, 2]
True
[1]

3.分析

new 方法为静态方法,init 为实例方法,根据python官方文档描述有:

1. 当创建一个实例的时候首先调用 new 方法,该方法的返回值一般为该类的实例对象

2. 当 new 方法有返回值且为实例对象时,调用一次 init 方法

3. 打印结果的 True 表示该示例确实限制了类只存在一个实例

4. 打印结果的 [1] 表示之前对实例变量的改变被重置,即在实例化 b 时执行了 init 方法 


二、通过函数装饰器实现

1.示例

def singleton(cls):
    _instance = {}
    def inner(*args, **kargs):
        if cls not in _instance:
            _instance[cls] = cls(*args, **kargs)
        return _instance[cls]
    return inner

@singleton
class test():
    def __init__(self, x) -> None:
        self.a = [x]


a = test(1)
a.a.append(2)
b = test(2)
print(id(a) == id(b))
print(a.a)
print(b.a)

2.打印结果

True
[1, 2]
[1, 2]

3.分析

打印结果布尔值 True 说明单例成功,两个 [1, 2] 打印结果说明实例的变量没有被重置

posted @ 2023-02-09 15:45  国家三级保护废物  阅读(22)  评论(0编辑  收藏  举报