认识单例模式

什么是单例模式

保证整个系统中一个类只有一个对象的实例,实现这种功能的方式就叫单例模式。

为什么要用单例模式?

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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值