python如何实现单例模式
单例模式
单例模式(Singleton Pattern) 是一种常用的软件设计模式,该模式的主要目的是确保 某一个类只有一个实例存在 。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。
比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 AppConfig 这样的类,我们希望在程序运行期间只存在一个实例对象。
在 Python 中,我们可以用多种方法来实现单例模式: 1.使用模块
其实, Python 的模块就是天然的单例模式 ,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。如果我们真的想要一个单例类,可以考虑这样做: # mysingleton.py class My_Singleton(object): def foo(self): pass my_singleton = My_Singleton()
将上面的代码保存在文件 mysingleton.py 中,然后这样使用:from mysingleton import my_singleton my_singleton.foo()2.使用 __new_# Create your tests here. class Singleton: def __init__(self, name): self.name = name def __new__(cls, *args, **kw): if not hasattr(cls, "_instance"): orig = super(Singleton, cls) cls._instance = orig.__new__(cls) return cls._instance one = Singleton("aa") two = Singleton("bb") print(one.name) print(one.name) two.a = 3 print(one.a) # one和two完全相同,可以用id(), ==, is检测 print(id(one)) print(id(two)) print(one == two) print(one is two) """ bb bb 3 140262441189328 140262441189328 True True """
加上锁 import time import threading class Singleton(object): _instance_lock = threading.Lock() def __init__(self): time.sleep(1) print(self) def __new__(cls, *args, **kwargs): with cls._instance_lock: if not hasattr(Singleton, "_instance"): Singleton._instance = object.__new__(cls) return Singleton._instance def task(): obj = Singleton() for i in range(10): t = threading.Thread(target=task) t.start()3.利用类实现单例模式:
不能支持多线程的单例模式class Singleton(object): @classmethod def instance(cls, *args, **kwargs): if not hasattr(Singleton, "_instance"): Singleton._instance = Singleton() return Singleton._instance a = Singleton.instance() b = Singleton.instance() print(a == b) # True
但是我们加上多线程试试 import time class Singleton(object): def __init__(self): time.sleep(1) @classmethod def instance(cls, *args, **kwargs): if not hasattr(Singleton, "_instance"): Singleton._instance = Singleton() return Singleton._instance # a=Singleton.instance() # b=Singleton.instance() # print(a==b) import threading def task(): obj = Singleton.instance() print(obj) for i in range(10): t = threading.Thread(target=task) t.start() """ <__main__.Singleton object at 0x0000022E579C6E80> <__main__.Singleton object at 0x0000022E579AB898> <__main__.Singleton object at 0x0000022E579EC6A0> <__main__.Singleton object at 0x0000022E579DB1D0> <__main__.Singleton object at 0x0000022E579EC5C0> <__main__.Singleton object at 0x0000022E579D1FD0> <__main__.Singleton object at 0x0000022E579D9C50> <__main__.Singleton object at 0x0000022E579C6F60> <__main__.Singleton object at 0x0000022E579D1EB8> <__main__.Singleton object at 0x0000022E579DB2B0> """
解决上面存在的问题,实现支持多线程的单列模式:import time import threading class Singleton(object): _instance_lock = threading.Lock() def __init__(self): time.sleep(1) @classmethod def instance(cls, *args, **kwargs): with cls._instance_lock: if not hasattr(Singleton, "_instance"): Singleton._instance = Singleton() return Singleton._instance def task(): obj = Singleton.instance() print(obj) for i in range(10): t = threading.Thread(target=task) t.start() """ <__main__.Singleton object at 0x7fd2ff82d990> <__main__.Singleton object at 0x7fd2ff82d990> <__main__.Singleton object at 0x7fd2ff82d990> <__main__.Singleton object at 0x7fd2ff82d990> <__main__.Singleton object at 0x7fd2ff82d990> <__main__.Singleton object at 0x7fd2ff82d990> <__main__.Singleton object at 0x7fd2ff82d990> <__main__.Singleton object at 0x7fd2ff82d990> <__main__.Singleton object at 0x7fd2ff82d990> <__main__.Singleton object at 0x7fd2ff82d990> """
创建实例只能调用Singleton.instance()来调用,不能用Singleton()来实现 四、基于metaclass方式实现
如果不清楚元类 可以参考这一篇文章:python元类的介绍import threading class Singleton(type): _instance_lock=threading.Lock() def __call__(cls, *args, **kwargs): with cls._instance_lock: if not hasattr(cls,"_instance"): cls._instance=super(Singleton, cls).__call__(*args, **kwargs) return cls._instance class Foo(metaclass=Singleton): def __init__(self,name): self.name=name obj1 = Foo("name") obj2 = Foo("name") print(obj1,obj2)
8090音乐回忆录之rh1SONYMDCD机的替代品,这款机器是索尼发布的最后一款MD机,搭载音效系统与NH1相仿,由于HiMD的出现,使MD碟片的容量有了巨大的进步,这个时期MD的音质已经可以与CD媲美,
中国股市稀缺程度胜过黄金的企业,就是这6家芯片龙头企业芯片未来的发展趋势这几年来,公共事件对全球都造成影响,全世界经济都处于缓慢发展的阶段。除此之外,芯片的需求量剧增,如果说石油关系到制造业的发展,那么毫不夸张地说,芯片就是信息技术的
如果互联网红利逐渐消失,程序员的工资也会降低吗?互联网红利消失?互联网哪有红利一说?程序员大不了自己干,收入比工资还高好吧我作为程序员出身,因为找工作确实不容易,自己购买的新加坡服务器,域名是也是在国外买的(godaddy),自
电钢琴科普电钢琴保养,调音,复音数,键盘,重锤,跨界钢琴?大家好,我是业余弹琴的胡迪,平时喜欢研究电钢琴和电钢琴,大家在购买电钢琴时有很多疑惑吧,这篇文章是我在浏览各大网站时发现很多新手对电钢琴的了解不是很多,这篇文章总结了几点电钢琴小知
I53470处理器更换I73770性能会有多大提升?我的办公室电脑就是用的i53470,应该说如果只是普通办公的话,i53470这颗四核CPU基本是够用了,我用这颗CPU加上8G内存和Gtx750显卡剪辑视频和PS处理高清图片问题都
1589元!骁龙8701亿像素50倍长焦镜头,友商更有诚意性价比的鼻祖应该是小米,以往的发布会,雷军每每公布价格,都会引发强烈的沸腾声和鼓掌声,现在小米走高端路线,性价比手机将由子品牌Redmi来接棒,Redmi的前身是红米,卢伟冰任命为
管理系统的好处是什么?规范化,目标化,才能达到一定的执行力!近年来,客户管理系统在企业应用软件市场爆发,其每年的销售额都在不断增加,CRM系统是企业实现数字化信息化转型的关键工具,已经有越来越多的企业意
徕卡校色有什么不同?新升级有哪些看点?坚果J10S智能投影仪体验春节前,刚帮妹妹家安装了一台坚果J10投影仪,没想到年后还没过完正月,作为升级款的坚果J10S智能投影仪就上市了。坚果J系列一直是坚果主打的高端智能家用投影仪系列,这次升级到底带来
2022年,如何实现家庭影院影音唱一体化?你有没有发现,近两年我们的娱乐方式正悄然地发生一些变化,因为疫情,我们的娱乐生活逐渐回归到家庭。以家庭娱乐为中心的相关行业或者相关产品,比如体感游戏,家庭健身,家庭影音,家庭K歌慢
这款游戏手机肿么样?本人游戏发烧友一枚,最主要的游戏就是王者农药和吃鸡,有主力机接打电话日常交流拍照,三个电话卡,有一个流量卡专门玩游戏,所以一直有游戏手机做备用机。rog123和黑鲨4都用过,现在准
西方金融游戏的本质是什么?1问传统的汽车工业是西方制造业仅存的优势行业之一,随着中国新能源汽车销售超出行业预期的突飞猛进,美欧日的汽车工业会如何面对?答西方的方法,一,全力阻止中国,这是目前正在做的。二,如