python单例设计模式
Posted tianliang-2000
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python单例设计模式相关的知识,希望对你有一定的参考价值。
理解单例模式
单例即为单个实例,也就是每次实例化创建对象时获得的都是同一个对象,当然同一个对象的属性都是相同的,方法也是相同的,地址也是相同的,这样给我们带来的好处就是可以避免消耗过多的内存或CPU资源,例如数据库类,我们希望每次都使用同一个数据库对象来对数据库进行操作,以维护数据的一致性。又如模块的导入,如果没有导入该模块,则导入该模块并实例化,如果已经导入,则返回该模块的对象。
1.基于new方法实现的单例模式
1 class Singleton(): 2 def __new__(cls, *args, **kwargs): 3 #利用反射检查判断该类是否有对象 4 if not hasattr(cls,‘instance‘): 5 #创建对象 6 cls.instance=super(Singleton,cls).__new__(cls) 7 return cls.instance 8 9 a=Singleton() 10 b=Singleton() 11 print(a)#<__main__.Singleton object at 0x00000220866EF400> 12 print(b)#<__main__.Singleton object at 0x00000220866EF400>
new方法为python实例化创建对象自动执行的函数,通过重写这个函数,使之先判断该类中是否有instance属性(利用反射),若没有则为创建一个对象并为该属性赋值,最后返回instance中的对象。通过这种方式我们实现了每次创建实例返回的都是类中的instance的值。
2.懒汉式实例化
1 class Singleton(): 2 __instance=None 3 4 def __init__(self): 5 pass 6 7 @classmethod 8 def getInstance(cls): 9 if not cls.__instance: 10 cls.__instance = Singleton() 11 return cls.__instance 12 13 a=Singleton.getInstance()#<__main__.Singleton object at 0x000001C85C114B38> 14 b=Singleton.getInstance()#<__main__.Singleton object at 0x000001C85C114B38> 15 print(a) 16 print(b)
注:获得实例一定要调用Singleton.getInstance()方法,直接a=Singleton()相当于没用单例。
3.基于元类的单例实现
1 class MetaSingleton(type): 2 __instance= 3 def __call__(self, *args, **kwargs): 4 if self not in MetaSingleton.__instance: 5 MetaSingleton.__instance[self] = super(MetaSingleton,self).__call__() 6 return MetaSingleton.__instance[self] 7 8 class Singleton(metaclass=MetaSingleton): 9 def __init__(self): 10 pass 11 12 a=Singleton()#<__main__.Singleton object at 0x0000025103984CC0> 13 b=Singleton()#<__main__.Singleton object at 0x0000025103984CC0> 14 print(a) 15 print(b)
执行Singleton()之后,首先会调用MetaSingleton中的call函数,如果Singleton类没有在instance中,则为其创建一个实例,也就是正常调用type中的call函数,将返回的对象存在instance中,以该类名为键,对象为值,最后返回这个对象,若instance中有该类,那就直接返回存储的对象。
这种方式我觉得较好,不用为每个类单独创建单例模式,只需将元类重写即可
以上是关于python单例设计模式的主要内容,如果未能解决你的问题,请参考以下文章