单例模式
单例模式
【一】什么是设计模式
- 解决问题的模板,大牛们会遇到各种各样的问题,长久一来就形成了一套相对规范的解决办法
【二】使用模式的好处
- 设计模式可以帮助开发人员编写高质量、可重用和易于维护的代码。
- 通过使用设计模式,开发人员可以避免重复劳动,并确保他们的代码遵循最佳实践和行业标准。
【三】设计模式的组成部分
【1】问题:有了问题才需要想解决办法
【2】解决方按:对上述问题拟定方案解决
【3】关键角色:到底应该用在哪里?谁来用我?
【四】常见的设计模式
- 常见的设计模式有单例模式、工厂模式、观察者模式、适配器模式、策略模式、装饰器模式、代理模式等。
【五】什么是单例模式
- 单例设计模式(Singleton Design Pattern): 一个类只允许创建一个对象(或者实例),那这个类就是一个单例类,这种设计模式就叫作单例设计模式,简称单例模式。
- 当一个类的功能比较单一,只需要一个实例对象就可以完成需求时,就可以使用单例模式来节省内存资源。
class MyMeta(type):
def __init__(cls, what, bases, dict):
print(f'这是 __init__ {cls}')
cls.instance = None
super().__init__(what, bases, dict)
def __new__(cls, *args, **kwargs):
obj = super().__new__(cls, *args, **kwargs)
print(f'这是 __new__ {obj}')
return obj
def __call__(self, *args, **kwargs):
# print(f'这是 __call__ {self}')
obj = super().__call__(*args, **kwargs)
# if hasattr(self, 'instance'):
# return getattr(self, 'instance')
if self.instance:
return self.instance
self.instance = obj
print(self.instance)
return obj
# 元类是控制类的产生的
# 元类里面的所有 self 如果不是你想产生的这个类
class School(metaclass=MyMeta):
...
# 控制对象的产生,我们要重写 元类中 的 __call__
s = School()
s1 = School()
print(id(s))
print(id(s1))
__init__
方法:在类被创建时调用。这个方法用于初始化类的属性和状态。在这里,我们设置了一个名为instance
的属性,用于保存类的唯一实例。__new__
方法:在类被创建时调用。这个方法用于创建类的实例。在这里,我们调用了父元类的__new__
方法来创建实例对象,并返回这个实例。__call__
方法:在类的实例被调用时调用。这个方法提供了类似函数调用的方式来创建对象。在这里,我们通过判断self.instance
是否存在来决定是否返回已有的实例。如果已有实例存在,则直接返回该实例;如果不存在,则创建一个新的实例,并将其保存到self.instance
中。
整体来说,这个元类实现了单例模式的逻辑。通过使用这个元类创建的类MyClass
,无论在何处创建实例,都会得到同一个对象。这样可以确保全局只有一个实例存在,并避免了资源浪费和状态不一致的问题。
【六】单例模式补充
# 定义元类
class MyMeta(type):
# 定义一个类属性
instance = None
# 类加() 触发 元类中的 __call__ 方法
def __call__(cls, *args, **kwargs):
# 类属性没赋值
if not cls.instance:
# 类属性 = 创建一个新的对象
cls.instance = object.__new__(cls)
# 对象.__init__ 初始化参数
cls.instance.__init__(*args, **kwargs)
# 类属性有值会返回相应的对象
return cls.instance
class School(metaclass=MyMeta):
def __init__(self, name):
self.name = name
def __new__(cls, *args, **kwargs):
print(args)
print(kwargs)
obj = super().__new__(cls, *args, **kwargs)
return obj
# 控制对象的产生,我们要重写 元类中 的 __call__
s = School(name='dream')
t = School(name='opp')
print(s.name)
print(t.name)
【七】单例模板
class SingletonType(type):
def __init__(cls, name, bases, attrs):
super(SingletonType, cls).__init__(name, bases, attrs)
cls.instance = None
def __call__(cls, *args, **kwargs):
if cls.instance is None:
cls.instance = super(SingletonType, cls).__call__(*args, **kwargs)
return cls.instance
class Singleton(metaclass=SingletonType):
pass
singleton_one = Singleton()
singleton_two = Singleton()
print(singleton_one)
# <__main__.Singleton object at 0x000001C0B531A770>
print(singleton_two)
# <__main__.Singleton object at 0x000001C0B531A770>
print(singleton_one is singleton_two)
# True
# 输出 True,表示是同一个实例
# # 使用 __call__ 方法获取单例
singleton_three = Singleton()
print(singleton_one is singleton_three)
# True