文章目录

    • 目标
  • 一、单例设计模式
    • 1.1 设计模式
    • 1.2 单例设计模式的应用场景
  • 二、 `__new__` 方法
    • 2.1 `__new__`方法作用
    • 2.2 示例代码
  • 三、Python 中的单例
    • 3.1 只执行一次初始化工作

目标

  • 单例设计模式
  • __new__ 方法
  • Python 中的单例

一、单例设计模式

1.1 设计模式

  • 设计模式

    • 设计模式前人工作的总结和提炼,通常,被人们广泛流传的设计模式都是针对 某一特定问题 的成熟的解决方案
    • 使用 设计模式 是为了可重用代码、让代码更容易被他人理解、保证代码可靠性
  • 单例设计模式
    • 目的 —— 让 创建的对象,在系统中 只有 唯一的一个实例
    • 每一次执行 类名() 返回的对象,内存地址是相同的

1.2 单例设计模式的应用场景

  • 音乐播放 对象
  • 回收站 对象
  • 打印机 对象
  • ……

二、 __new__ 方法

2.1 __new__方法作用

  • 使用 类名() 创建对象时,Python 的解释器 首先 会 调用 __new__ 方法为对象 分配空间

  • __new__ 是一个 由 object 基类提供的 内置的静态方法,主要作用有两个:

    1. 在内存中为对象 分配空间

    2. 返回 对象的引用

  • Python 的解释器获得对象的 引用 后,将引用作为 第一个参数,传递给 __init__ 方法

__new__ 方法 的代码非常固定!

2.2 示例代码

class MusicPlayer(object):def __new__(cls, *args, **kwargs):# 1. 创建对象时,new方法会被自动调用print("创建对象,分配空间")   # 覆盖了父类方法实现# 2. 为对象分配空间instance = super().__new__(cls)# 3. 返回对象的引用,给python解释器return instancedef __init__(self):print("播放器初始化")# 创建播放器对象
player = MusicPlayer()print(player)

创建对象,分配空间
播放器初始化
<main.MusicPlayer object at 0x000001FEB7F623C8>

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

三、Python 中的单例

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

class MusicPlayer(object):# 记录第一个被创建对象的引用instance = Nonedef __new__(cls, *args, **kwargs):# 1. 判断类属性是否是空对象;如果是空对象,说明第一个对象还没有被创建if cls.instance is None:# 2. 如果第一个对象没创建,调用父类的方法,为第一个对象分配空间==>才能用类属性进行记录cls.instance = super().__new__(cls)# 3. 返回类属性保存的对象引用return cls.instance# 创建对象
player = MusicPlayer()
print(player)

<main.MusicPlayer object at 0x00000253D38423C8>

3.1 只执行一次初始化工作

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

    • __new__ 分配空间
  • __init__ 对象初始化

  • 在上一小节对 __new__ 方法改造之后,每次都会得到 第一次被创建对象的引用

  • 但是:初始化方法还会被再次调用

需求

  • 初始化动作 只被 执行一次

解决办法

  1. 定义一个类属性 init_flag 标记是否 执行过初始化动作,初始值为 False
  2. __init__ 方法中,判断 init_flag,如果为 False 就执行初始化动作
  3. 然后将 init_flag 设置为 True
  4. 这样,再次 自动 调用 __init__ 方法时,初始化动作就不会被再次执行
class MusicPlayer(object):# 记录第一个被创建对象的引用instance = None# 记录是否执行过初始化动作(重要)init_flag = Falsedef __new__(cls, *args, **kwargs):# 1. 判断类属性是否是空对象if cls.instance is None:# 2. 调用父类的方法,为第一个对象分配空间cls.instance = super().__new__(cls)# 3. 返回类属性保存的对象引用return cls.instancedef __init__(self):# 1. 判断是否执行过初始化动作if MusicPlayer.init_flag:  # 判断类属性return# 2. 如果没有执行过,在执行初始化动作print("初始化播放器")# 3. 修改类属性的标记MusicPlayer.init_flag = True# 创建多个对象
player1 = MusicPlayer()
print(player1)player2 = MusicPlayer()
print(player2)

初始化播放器
<main.MusicPlayer object at 0x0000015A111219B0>
<main.MusicPlayer object at 0x0000015A111219B0>

提示:初始化执行完成,类属性标记就被设置为真,下一次再次调用初始化方法的时候,类属性标记为真就直接返回,而不会执行下方的初始化动作。

21_python基础—单例和 __ new __ 方法相关推荐

  1. Java查漏补缺(08)关键字:static、单例设计模式、理解main方法、类的成员之四:代码块、final关键字、抽象类、接口、内部类、枚举类、注解、包装类

    Java查漏补缺(08)关键字:static.单例设计模式.理解main方法.类的成员之四:代码块.final关键字.抽象类.接口.内部类.枚举类.注解.包装类 本章专题与脉络 1. 关键字:stat ...

  2. java单例的几种实现方法

    java单例的几种实现方法: 方式1: public class Something { private Something() {}private static class LazyHolder { ...

  3. was修改类加载模式_java基础——单例(Singleton)模式介绍

    基本概括 详解 一.单例模式定义: 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 二.单例模式特点: 1.单例类只能有一个实例. 2.单例类必须自己创建自己的唯一实例. 3 ...

  4. 【Java】day9--main方法、单例设计模式、继承、方法重写部分知识点总结

    (一)main方法 jvm调用main方法,jvm也是一个程序     main方法详解:         public:公共  保证该类在任何情况下,jvm都对其方法可见.         stat ...

  5. Java基础 - 单例(饿汉、懒汉),2年以上经验必看

    //r.exec("shutdown -s -t 300"); //300秒后关机r.exec("shutdown -a"); ``` 3.Timer(掌握) ...

  6. Java基础学习系列--(二)【抽象类,接口、代码块、final、单例、枚举】

    第一章 抽象类 1.1 概述 1.1.1 抽象类引入 父类中的方法,被它的子类们重写,子类各自的实现都不尽相同.那么父类的方法声明和方法主体,只有声明还有意义,而方法主体则没有存在的意义了(因为子类对 ...

  7. Java(基础)单例(Singleton)

    设计模式是在大量的实践中总结和理论化之后优选的代码结构.编程风格. 以及解决问题的思考方式.设计模免去我们自己再思考和摸索.就像是经典 的棋谱,不同的棋局,我们用不同的棋谱."套路" ...

  8. Spring IOC 容器源码分析 - 创建单例 bean 的过程

    1. 简介 在上一篇文章中,我比较详细的分析了获取 bean 的方法,也就是getBean(String)的实现逻辑.对于已实例化好的单例 bean,getBean(String) 方法并不会再一次去 ...

  9. day02-抽象类,接口、代码块、final、单例、枚举

    java基础[抽象类,接口.代码块.final.单例.枚举] 第一章 抽象类 1.1 概述 1.1.1 抽象类引入 父类中的方法,被它的子类们重写,子类各自的实现都不尽相同.那么父类的方法声明和方法主 ...

最新文章

  1. 设计模式我学过呀,就是没用过
  2. linux命令安装openssl函数库,ubuntu安装openssl库
  3. 6.SQL Server Sql语句
  4. asch相关的linux基础知识分享
  5. r语言中矩阵QR分解_从零开始学R语言Day4|向量、矩阵和数组
  6. jdbc,mybatis,hibernate各自优缺点及区别
  7. ***是如何能破解诸如美国中情局之类的密码
  8. 手机调试_手机充值不好用?因为正在调试期
  9. JDK11+Tomcat10 下载安装+环境配置
  10. Atitit sql执行计划
  11. Dagger 2 系列(一) -- 前奏篇:依赖注入的基本介绍
  12. ubuntu下Qt cannot find -lGL错误的解决方法
  13. 【图像去噪】基于matlab GUI均值+中值+高通低通+巴特沃斯+PCA+小波+维纳滤波图像去噪【含Matlab源码 1705期】
  14. linux密码忘记重新设置密码
  15. 基于STM32的MLX90614(GY-906)人体红外测温
  16. CentOs下安装pip3
  17. android 自定义数字软键盘,(笔记)Android自定义数字键盘
  18. Gym - 101177K Kiwis vs Kangaroos 水题手动打表
  19. 电流输入放大器的设计
  20. 小程序中如何关注公众号

热门文章

  1. C语言课后习题(20)
  2. MySQL 8.0 表空间机制
  3. DBA邀请函丨数据库大咖讲坛来深圳啦!线下沙龙+线上直播,共享技术盛会!
  4. 二月技术通讯.pdf丨核心数据库一波三折异常重启分析
  5. 每周精选:20万DBA都在关注的11个问题
  6. 一文了解GaussDB 200的产品架构、数据流程、组网方案、服务部署原则、企业级增强特性......
  7. 解析HetuEngine实现On Yarn原理
  8. 深度学习分类任务常用评估指标
  9. 用好CloudIDE提升Web全栈编码效率
  10. 安全性能两手抓,华为云MySQL“非双一特性”助力企业业务稳定高效运行