前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python单例设计模式【详细】

Python单例设计模式【详细】

原创
作者头像
python自学网
发布2022-09-29 16:47:27
7671
发布2022-09-29 16:47:27
举报
文章被收录于专栏:python+前端 知识分享

一、设计模式和单例设计模式概念

1)设计模式:

含义:

设计模式是前人工作的总结和提炼,通常被人们广泛的设计模式都是针对某一特定的问题的成熟的解决方案。

作用:

使用设计模式是为了可重用代码,让代码更容易被他人理解,保证代码的可靠性。

2)单例设计模式:

目的:

  • 让类创建的对象在系统中只有唯一的一个实例
  • 每一次执行 类名() 返回的对象,内存地址是相同的

3)单例设计模式应用场景

场景:

音乐播放对象(每次播放只能播放一首歌曲)

回收站对象(电脑中只有一个回收站)

......

共同特点:

这两个对象都只有唯一的存在

二、__new__方法

__new__方法(new字母前后分别是两个英文状态下的下划线,用两个下划线开头两个下划线结尾的方法是内置方法)

1)使用类名()创建对象时,Python解释器做的2件事:

  1. 使用 类名() 创建对象时,Python解释器首先会调用__new__方法为对象分配空间
  2. Python的解释器获得对象的引用后,将引用作为第一个参数,传递给__init__方法

简单理解就是: 第一件事是为对象分配空间,第二件事是给对象初始化。

__new__是一个由object基类提供的内置的静态方法。

主要作用有2个:

  1. 在内存中为对象分配空间
  2. 返回对象的引用

2)重写__new__方法的代码非常固定:

  1. 重写__new__方法一定要返回分配了空间return super().__new__(cls)
  2. 否则Python的解释器得不到分配了空间的对象引用,就不会调用对象的初始化方法 注意: __new__是一个静态方法,在调用时需要主动传递cls参数

3)重写__new__方法代码演练

简单代码:

代码语言:python
代码运行次数:0
复制
class MusicPlayer(object):

    def __init__(self):
        print("播放器对象初始化")


# 创建播放器对象
player = MusicPlayer()

print(player)

执行结果:

重写object基类提供的__new__方法代码1:

代码语言:python
代码运行次数:0
复制
class MusicPlayer(object):
    def __new__(cls, *args, **kwargs):

        # 1. 创建对象时,new方法会被自动调用
        print("创建对象自动调用new方法,分配空间")

    def __init__(self):
        print("播放器对象初始化")


# 创建播放器对象
player = MusicPlayer()

print(player)

执行结果:

None:因为重写__new__方法没有返回分配了空间return super().__new__(cls),此时Python的解释器得不到分配了空间的对象引用,就不会调用对象的初始化方法。

重写object基类提供的__new__方法代码2(完整):

代码语言:python
代码运行次数:0
复制
class MusicPlayer(object):
    def __new__(cls, *args, **kwargs):

        # 1. 创建对象时,new方法会被自动调用
        print("创建对象自动调用new方法,分配空间")

        # 2. 为对象分配空间
        # super():父类方法
        instance = super().__new__(cls)

        # 3. 返回对象的引用
        return instance

    def __init__(self):
        print("播放器对象初始化")


# 创建播放器对象
player = MusicPlayer()

print(player)

执行结果:

三、Python中的单例

1)单例设计模式思路分析

单例 —— 让类创建的对象,在系统中只有唯一的一个实例(也就是使用这个类无论创建多少次对象都是同一个对象)

思路分析:

  1. 定义同一个类属性,初始值是None用于记录单例对象的引用
  2. 重写__new__方法
  3. 如果类属性is None调用父类方法分配空间,并在类属性中记录结果
  4. 返回类属性中记录的对象引用

2)实现单例设计模式——验证是否是同一个对象

1.验证前准备,确定此时不是同一个对象:

代码:

代码语言:python
代码运行次数:0
复制
class MusicPlayer(object):
    pass


# 创建多个对象,对比地址是否相同
player1 = MusicPlayer()
print(player1)

player2 = MusicPlayer()
print(player2)

执行结果:地址不同

2.验证单例设计模式是不是同一个对象:

代码:

代码语言:python
代码运行次数:0
复制
class MusicPlayer(object):
    # 记录第一个被创建对象的引用
    instance = None

    def __new__(cls, *args, **kwargs):

        # 1. 判断类属性是否是一个空对象,没有是空对象,说明第一个对象还没被创建
        if cls.instance is None:
            # 2. 调用父类的方法,为第一个对象分配空间
            cls.instance = super().__new__(cls)

        # 3. 返回类属性保存的对象引用
        return cls.instance


# 创建多个对象,对比地址是否相同
player1 = MusicPlayer()
print(player1)

player2 = MusicPlayer()
print(player2)

执行结果:地址相同,证明这两个对相关本质上是相同对象

四、只执行一次初始化方法

在每次使用类名() 创建对象时,Python解释器都会自动调用者两个方法:

__new__ 分配空间

__init__ 对象初始化

在上面的代码对__new__方法改造之后,每次都会得到第一次被创建对象的引用,但是初始化方法还是会被再次调用。

需求:让初始化动作只被执行一次。

解决办法:

  1. 定义一个类属性init_flag标记是否执行过初始化动作,初始值为False
  2. 在__init__方法中判断init_flag,如果为False就执行初始化动作
  3. 然后将init_flag设置为True,这样再次调用__init__方法时,初始化动作就不会被再次执行了

1.代码实现前准备,创建了两次对象,初始化方法被执行两次:如图

2.初始化动作只被执行一次的代码:

代码语言:python
代码运行次数:0
复制
class MusicPlayer(object):
    # 记录第一个被创建对象的引用
    instance = None
    # 记录是否执行初始化动作
    init_flag = False

    def __new__(cls, *args, **kwargs):

        # 1. 判断类属性是否是一个空对象,没有是空对象,说明第一个对象还没被创建
        if cls.instance is None:
            # 2. 调用父类的方法,为第一个对象分配空间
            cls.instance = super().__new__(cls)

        # 3. 返回类属性保存的对象引用
        return cls.instance

    def __init__(self):

        # 1. 判断是否执行过初始化动作
        if MusicPlayer.init_flag:
            return
        # 2. 如果没有被执行过,再执行初始化动作
        print("初始化方法执行")

        # 3. 修改类属性init_flag的值为True
        MusicPlayer.init_flag = True


# 创建多个对象,对比地址是否相同
player1 = MusicPlayer()
print(player1)

player2 = MusicPlayer()
print(player2)

增加代码:

执行结果:

更多相关Python教程可以移步去Python自学网(http://www.wakey.com.cn/)从基础入门免费课程开始,逐步深入学习python全栈体系课程,适合新手入门到精通全栈开发。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、设计模式和单例设计模式概念
    • 1)设计模式:
      • 2)单例设计模式:
        • 3)单例设计模式应用场景
        • 二、__new__方法
          • 1)使用类名()创建对象时,Python解释器做的2件事:
            • 2)重写__new__方法的代码非常固定:
              • 3)重写__new__方法代码演练
              • 三、Python中的单例
                • 1)单例设计模式思路分析
                  • 2)实现单例设计模式——验证是否是同一个对象
                    • 1.验证前准备,确定此时不是同一个对象:
                • 四、只执行一次初始化方法
                相关产品与服务
                日志服务
                日志服务(Cloud Log Service,CLS)是腾讯云提供的一站式日志服务平台,提供了从日志采集、日志存储到日志检索,图表分析、监控告警、日志投递等多项服务,协助用户通过日志来解决业务运维、服务监控、日志审计等场景问题。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档