ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2022-07-05 13:00:35  阅读:188  来源: 互联网

标签:__ db2 instance python DB -- 实例 设计模式 cls


►使用场景

 

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

 

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

 

►python实现

 

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

 

重写__new__

 

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

 

class DB:    instance = None

def __new__(cls, *args, **kwargs):
    if cls.instance is None:

      cls.instance = super().__new__(cls, *args, **kwargs)

    return cls.instance

db1 = DB()

db2 = DB()

print(db1)print(db2)
 

运行代码结果如下:

 

<__main__.DB object at 0x000001BD06E55F70>

<__main__.DB object at 0x000001BD06E55F70>

 

►装饰器

 

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

 

def single_obj(cls):   
   def wrapper(*args, **kwargs):

    if cls.instance is None:

       cls.instance = cls(*args, **kwargs)

    return cls.instance
return wrapper
@single_obj
class DB:
  instance = None

db1 = DB()

db2 = DB()

print(db1)print(db2)

 

运行代码结果如下:

 

<__main__.DB object at 0x000001E485395970>

<__main__.DB object at 0x000001E485395970>

 

►元类

 

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

 

class SingleObj(type):     
  def __call__(cls, *args, **kwargs):

    if getattr(cls, 'instance', None) is None:

      cls.instance = super().__call__(*args, **kwargs)

     return cls.instance

class DB(metaclass=SingleObj):
   pass

db1 = DB()
db2 = DB()
print(db1)print(db2)

 

代码运行结果如下:

 

<__main__.DB object at 0x00000252D5AE4F70>

<__main__.DB object at 0x00000252D5AE4F70>

 

标签:__,db2,instance,python,DB,--,实例,设计模式,cls
来源: https://www.cnblogs.com/Wl55387370/p/16445996.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有