Python之单例模式
单例模式基本概念
''' 1、什么是单例模式 单例模式:基于某种方法实例化多次得到实例是同一个 2、为何用单例模式 当实例化多次得到的对象中存放的属性都一样的情况,应该将多个对象指向同一个内存地址,即同一个实例 3、如何用 '''
一、使用类的方法
# 单例模式实现一: """ 定义一个类,由类来调用,完成单例的调用过程""" #配置文件settings内容: """ IP='0.0.0.1' PORT=3306 """ import settings class Mysql: __instance=None #通过数据属性来记录用户调用类的方法实例化的状态,调用前状态为Nnoe def __init__(self,ip,port): self.ip=ip self.port=port #在类当中定义了一个类方法 @classmethod def from_conf(cls): #-----------------------将该方法装饰成由类来调用的方法,类来调用将类自动传入 if cls.__instance is None: #-----------------------判断该类是否是首次调用该方法,是则返回True cls.__instance=cls(settings.IP,settings.PORT) #类从配置文件中读参数,实例化出的实例(实例即调用类产生的对象) #成立与否都返回,所以再外部返回,不用使用else,重复返回 return cls.__instance #-----------------------当该方法是第一次和不是第一次被类调用,则返回的结果均是cls.__instance #单例模式多次都用返回得到的是同一个内存地址 obj1=Mysql.from_conf() #-----------------------类来调用被装饰器装饰的该方法,将类当做第一个参数自动传入 obj2=Mysql.from_conf() #-----------------------实例化没有传参,直接从配置文件读,每次调用该方法,实例化的结果都一样,所以叫做单例 obj3=Mysql.from_conf() #单列模式的好处就是不用每次都进行传参 print(obj1) print(obj2) print(obj3) print(obj1.__dict__) #{'ip': '0.0.0.1', 'port': 3306}-----从配置文件中类直接调用绑定给类的方法得到的结果 obj4=Mysql('10.10.10.11',3307) #直接调用类来是实例化,进行传参,对产生的对象进行初始化,可以和调用类的方法从配置文件中读得到形同的结果 print(obj4) print(obj4.__dict__) #{'ip': '10.10.10.11', 'port': 3307},类直接传参,实例化得到的结果
二、使用装饰器
# 单例模式实现二: """自定义一个装饰器,由装饰器来完成单例的过程""" # 实例化的时候不传参,代表触发单例模式 import settings '''--------------------------------------------------定义一个装饰器--------------------------------------------''' def singleton(cls): #定义一个单例模式的函数,把类当做形参 _instance=cls(settings.IP,settings.PORT) #也可以方法类中cls. _instance=cls(settings.IP,settings.PORT) def wrapper(*args,**kwargs): if len(args)==0 and len(kwargs)==0: #Mysql不传参时,直接返回调用类拿到settings中的对象,如果调用类传参了,那么我们就返回类直接调用的产生对象的结果 return _instance #cls._instance return cls(*args,**kwargs) #直接调用类(进行传参,对产生的随行进行初始化)的返回结果 return wrapper '''--------------------------------------------------定义一个装饰器--------------------------------------------''' @singleton #Mysql=singleton(Mysql) Mysql=wrapper-----没学类之前我们只学类用装饰器装饰函数,现在用自定义装饰器装饰类 class Mysql: def __init__(self,ip,port): self.ip=ip self.port=port obj1=Mysql() #单例模式每次调用类不用为其进行传参,就如同为ATM的一些功能加上登录装饰器一样,每次登录执行这些功能,必须先登录 obj2=Mysql() #不传参,每次调用时,就会执行自定义装饰器中的代码,就会从配置文件中读取内容:_instance=cls(settings.IP,settings.PORT) obj3=Mysql() print(obj1) #<__main__.Mysql object at 0x000002375BAC2E80> print(obj2) #<__main__.Mysql object at 0x000002375BAC2E80> print(obj3) #<__main__.Mysql object at 0x000002375BAC2E80> obj4=Mysql('0.0.0.3',3308) #直接传参,经过装饰器时,会直接走:cls(*args,**kwargs) ,直接调用Mysql,对产生的对象obj4:进行初始化__init__(self,ip,port) print(obj4) #<__main__.Mysql object at 0x0000023762ADBF98>
三、使用元类
# 单例模式实现三 """自定义一个元类,通过元类内的__call__来完成单例的过程""" # 基于元类不传参,从配置文件中读取相同的配置文件,传参则以自己传参的为准 import settings class Mymeta(type): def __init__(self,class_name,class_basess,class_dic): #self=Mysql super(Mymeta,self).__init__(class_name,class_basess,class_dic) #继承元类中的属性 self.__instance=self.__new__(self) #造出Mysql的空对象 self.__init__(self.__instance,settings.IP,settings.PORT) #对Mysql的空对象从配置文件中传参进行初始化 def __call__(self, *args, **kwargs): #会在调用类这个对象是自动触发 if len(args)==0 and len(kwargs)==0: #判断如果不传参时,直接返回我们从配置文件中初始会的对象 return self.__instance #返回配置文件中初始化的对象 # 否则即用户进行传参,而不是从配置文件中读取,那么我们就造一个空对象,然后对空对象那个进行初始化 obj=self.__new__(self) #传参的结果:也是想初始化一个空对象 self.__init__(obj,*args,**kwargs) #会原封不动的接收调用类这个对象传进来的参数,完成对调用类产生的空对象的初始化 return obj #将初始化的对象返回 class Mysql(object,metaclass=Mymeta): def __init__(self,ip,port): self.ip=ip self.port=port obj1=Mysql() #不传参直接调用类,产生对象,此时的对象,已经从配置文件中读取了配置信息,而非是一个空对象 obj2=Mysql() #每次调用该类读的是同一个配置文件,得到的对象的内存地址也是一样的 obj3=Mysql() # 以上三者调用均是没有进行传参,调用类这个对象会触发__call__,会判断如果没有进行传参,则直接调用配置文件拿到返回的结果 print(obj1) #<__main__.Mysql object at 0x000002659486F2E8> print(obj2) print(obj3) obj4=Mysql('0.0.0.3',3308) #直接为类进行传参,进过判断就不会走配置文件了,而是直接造了一个空对象,然后对其进行初始化 print(obj4) #<__main__.Mysql object at 0x000002659B88BF98>
python之基础知识大全
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?