• 3分钟学会设计模式 -- 单例模式


    ►使用场景

    在编写软件时,对于某些类来说,只有一个实例很重要。例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统中可以多次查询数据库,但是只需要一个连接,而不是每次查询都重新创建一个连接,因为重复创建数据库连接会浪费内存资源。因此这种情况下确保系统中某个对象的唯一性即一个类只能有一个实例非常重要。

    如何保证一个类只有一个实例并方便访问呢?定义一个全局变量可以确保对象随时可以访问,但不能防止实例化多个对象。一个更好的解决办法是让类自身负责保存它的唯一实例。这个类可以保证没有其他实例被创建,并且它可以提供一个访问该实例的方法。这就是单例模式的使用场景。

    ►python实现

    python中实现单例模式的方法很多,常用方法如下:

    重写__new__

    类实例化时是调用__new__方法创建对象的,所以只要控制__new__方法创建对象是只生成一个实例即可。

    1. class DB:
    2. instance = None
    3. def __new__(cls, *args, **kwargs):
    4. if cls.instance is None:
    5. cls.instance = super().__new__(cls, *args, **kwargs)
    6. return cls.instance
    7. db1 = DB()
    8. db2 = DB()
    9. print(db1)
    10. print(db2)

    运行代码结果如下:

    1. <__main__.DB object at 0x000001BD06E55F70>
    2. <__main__.DB object at 0x000001BD06E55F70>

    ►装饰器

    将类的唯一实例保存在类属性上,然后通过类装饰器,在实例化时检查这个属性来控制只生成一个实例。

    1. def single_obj(cls):
    2. def wrapper(*args, **kwargs):
    3. if cls.instance is None:
    4. cls.instance = cls(*args, **kwargs)
    5. return cls.instance
    6. return wrapper
    7. @single_obj
    8. class DB:
    9. instance = None
    10. db1 = DB()
    11. db2 = DB()
    12. print(db1)
    13. print(db2)

     运行代码结果如下:

    1. <__main__.DB object at 0x000001E485395970>
    2. <__main__.DB object at 0x000001E485395970>

    ►元类

    python中元类是用于创建类对象的类,类对象创建实例对象时一定会调用__call__方法,因此重写元类的__call__方法,保证在调用__call__时只创建一个实例即可。

    1. class SingleObj(type):
    2. def __call__(cls, *args, **kwargs):
    3. if getattr(cls, 'instance', None) is None:
    4. cls.instance = super().__call__(*args, **kwargs)
    5. return cls.instance
    6. class DB(metaclass=SingleObj):
    7. pass
    8. db1 = DB()
    9. db2 = DB()
    10. print(db1)
    11. print(db2)

    代码运行结果如下:

    1. <__main__.DB object at 0x00000252D5AE4F70>
    2. <__main__.DB object at 0x00000252D5AE4F70>

    最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

  • 相关阅读:
    OceanMind海睿思受邀出席ISACA中国2024年度大会,获国际审计数字信任先锋奖
    NSS [NISACTF 2022]is secret
    西安共享股东分红系统开发详细介绍
    java项目之小说阅读网站(ssm源码+文档)
    通达信软件L2接口的委托队列有什么用?
    使用 nlohmann 解析 json 文件
    yolov5训练模型
    【Python】数据处理:SQLite操作
    将网站上的点击作为转化操作进行跟踪-官方指导文档
    Halcon (3):窗体常用语法使用
  • 原文地址:https://blog.csdn.net/qq_73332379/article/details/133501625