什么是单例模式
保证整个系统中一个类只有一个对象的实例,实现这种功能的方式就叫单例模式。
为什么要用单例模式?
1、单例模式节省公共资源
比如:大家都要喝水,但是没必要每人家里都打一口井是吧,通常的做法是整个村里打一个井就够了,大家都从这个井里面打水喝。
对应到我们计算机里面,像日志管理、打印机、数据库连接池、应用配置。
2、单例模式方便控制
就像日志管理,如果多个人同时来写日志,你一笔我一笔那整个日志文件都乱七八糟,如果想要控制日志的正确性,那么必须要对关键的代码进行上锁,只能一个一个按照顺序来写,而单例模式只有一个人来向日志里写入信息方便控制,避免了这种多人干扰的问题出现。
实现单例的几种方式
1.模块
class myseling:
def foo(self):
pass
sing = myseling()
print(sing)
从num.py导入调用sing模块
from num1 import sing
sing
<num1.myseling object at 0x00000152BFD6A588>
2装饰器实现
我们知道,装饰器可以动态的修改一个类或函数的功能。这里,我们也可以使用装饰器来装饰某个类,使其只能生成一个实例:
def singleton(cls):
instance = {}
def getinstance(*args,**kwargs):
if cls not in instance:
instance[cls] =cls(*args,**kwargs)
return instance[cls]
return getinstance
@singleton
def Myinstance():
a=1
c1 = Myinstance()
c2 = Myinstance()
print(c1==c2) # True
这里表示instance初始化
如果不存在,则会将 cls 作为 key,cls(*args, **kw) 作为 value 存到 instances 中,每次调用都是一致的,否则,直接返回 instances[cls]。
3 使用__new__
class Singleton(object):
def __init__(self):
pass
def __new__(cls):
# 关键在于这,每一次实例化的时候,我们都只会返回这同一个instance对象
if not hasattr(cls, 'instance'):
cls.instance = super(Singleton, cls).__new__(cls)
return cls.instance
obj1 = Singleton()
obj2 = Singleton()
print(obj1==obj2) # true
或者
class MusicPlayer(object):
# 定义一个类属性,用于记录单例对象的引用
instance = None
# 记录是否执行初始化动作
init_flag = False
def __new__(cls, *args, **kwargs):
# 判断类属性是否已经被赋值
if cls.instance is None:
cls.instance = super().__new__(cls)
# print(cls.instance)
# 返回类属性的单例引用
return cls.instance
def __init__(self):
if not MusicPlayer.init_flag:
print("初始化音乐播放器")
MusicPlayer.init_flag = True
player = MusicPlayer()
player1 = MusicPlayer()
print(player)
print(player1)
运行后
初始化音乐播放器
<__main__.MusicPlayer object at 0x0000029EF636A708>
<__main__.MusicPlayer object at 0x0000029EF636A708>