单例模式定义

首次实例化创建实例化对象

之后的每次实例化都用最初的实例化对象 即单实例模式

__new__ 的原理

__new__ 方法可以在 __init__ 方法执行

这样可以在初始化之前进行一系列的其他操作

比如在这里创建一个全局实例

实现代码

class A:
__instance = False # 定义一个私有的变量,只能内部的去拿 def __init__(self, name, age):
self.name = name
self.age = age def __new__(cls, *args, **kwargs):
if cls.__instance: # 第一次循环外部拿不到自然就是 False
return cls.__instance
else:
# cls.__instance = object.__new__(A) # 借助object类创建的实例并赋值
cls.__instance = super().__new__(A) # 当然也可以借助 super 方法 return cls.__instance

关于使用父类方法的时候, super 方法是很好用的选择. 3.0版本中super 使用更加简单

代码分析

第一次创建的__instance变量一定是 false 的
因此必然返回一个借助 object 类创建的实例并赋值
所创建的这个实例是什么都没有的,没有self的属性,只是开辟了一段空的内存地址给他用
之后在调用 __init__ 根据你的参数赋值属性添加内存 __instance 是保存在类里面的静态变量 以后每次进来都是使用 cls.__instance 作为实例了

测试结果

a = A("a", 2)
a.cloth = "女装"
b = A("b", 2)

测试单例

print(b)
print(a)
"""
<__main__.A object at 0x000000000255D208>
<__main__.A object at 0x000000000255D208>
"""

结果

测试实例属性覆盖

print(a.name)
print(b.name)
"""
# 在创建示例会覆盖之前的实例的属性,但是两个示例都是存在的
b
b # name 和age 都会被下一次实例化的时候被新值锁覆盖
"""

结果

测试实例额外属性

print(a.cloth)
print(b.cloth)
"""
none # 尽管使用一个内存地址但是cloth 的属性没有被覆盖,而且保存在地址里面也不会被清除
none # sb示例并没有创建 cloth 属性,但是依然可以调用出来之前 suyang 示例的属性 ,即继承了之前的属性
"""

结果

测试实例属性覆盖

b.hobby = "bb"
print(a.hobby)
"""
bb # 相同的没有创建 hobby 的 suyang 示例 也可以继承之后的 sb 创建的 hobby 属性
"""

结果

全部代码

class A:
__instance = False # 定义一个私有的变量,只能内部的去拿 def __init__(self, name, age):
self.name = name
self.age = age def __new__(cls, *args, **kwargs):
if cls.__instance: # 第一次循环外部拿不到自然就是 False
return cls.__instance
else:
# cls.__instance = object.__new__(A) # 借助object类创建的实例并赋值
cls.__instance = super().__new__(A) # 当然也可以借助 super 方法 return cls.__instance """
第一次创建的__instance变量一定是 false 的
因此必然返回一个借助 object 类创建的实例并赋值
所创建的这个实例是什么都没有的,没有self的属性,只是开辟了一段空的内存地址给他用
之后在调用 __init__ 根据你的参数赋值属性添加内存 __instance 是保存在类里面的静态变量 以后每次进来都是使用 cls.__instance 作为实例了
""" a = A("a", 2)
a.cloth = "女装"
b = A("b", 2) print(b)
print(a)
"""
<__main__.A object at 0x000000000255D208>
<__main__.A object at 0x000000000255D208>
""" print(a.name)
print(b.name)
"""
# 在创建示例会覆盖之前的实例的属性,但是两个示例都是存在的
b
b # name 和age 都会被下一次实例化的时候被新值锁覆盖
""" print(a.cloth)
print(b.cloth)
"""
none # 尽管使用一个内存地址但是cloth 的属性没有被覆盖,而且保存在地址里面也不会被清除
none # sb示例并没有创建 cloth 属性,但是依然可以调用出来之前 suyang 示例的属性 ,即继承了之前的属性
""" b.hobby = "bb"
print(a.hobby)
"""
bb # 相同的没有创建 hobby 的 suyang 示例 也可以继承之后的 sb 创建的 hobby 属性
"""

全部代码

基于 __new__ 方法的单例模式的更多相关文章

  1. python学习-(__new__方法和单例模式)

    class Dog(object): __instance = None __init_flag = False def __new__(cls, name): if cls.__instance = ...

  2. python 单例模式,一个类只能生成唯一的一个实例,重写__new__方法详解

    单例:一个类只能生成唯一的一个实例 每个类只要被实例化了,他的私有属性 '_instance'就会被赋值,这样理解对吗 对 #方法1,实现__new__方法 #并在将一个类的实例绑定到类变量_inst ...

  3. 详解python中的__init__与__new__方法

    一.__init__和__new__方法执行的顺序? 在面向对象中介绍了关于对象创建的过程,我们知道__new__方法先于__init__方法执行. 二.__new__方法是什么? 首先,我们先来看下 ...

  4. python 中的__new__方法

    1.有关__new__方法的介绍 __new__方法调用在构造方法构造实例之前,即在__init__方法执行之前,我们可以这样理解,他的作用是决定是否适用这个__iint__方法来构造实例,但是需要注 ...

  5. Python构造方法、析构方法和单例模式

    一.__init__()方法 __init__()通常在初始化一个类实例的时候调用,如: class Student(object): def __init__(self,name,age): sel ...

  6. python面向对象之__new__方法

    众所周知,python中定义的类在创建实例对象的时候,会自动执行__init__()方法,但是在执行__init__()方法之前,会执行__new__()方法. __new__()的作用主要有两个. ...

  7. python使用__new__创建一个单例模式(单例对象)

    #单例模式:使一个类只产生一个对象.他们的id地址都指向同一个内存地址 第一步:理解谁创建了对象 # 单例模式# 首先明白,我们在创建一个类的对象的时候,其实是调用的这个类的父类,即继承object, ...

  8. day20-双下new方法,单例模式

    # 1. __new__:构造方法,它创造对象,程序员口头语:new一个对象.先执行__new__方法再执行___init__方法. class Goods: def __init__(self):# ...

  9. Spring-Context之六:基于Setter方法进行依赖注入

    上文讲了基于构造器进行依赖注入,这里讲解基于Setter方法进行注入.在Java世界中有个约定(Convention),那就是属性的设置和获取的方法名一般是:set+属性名(参数)及get+属性名() ...

随机推荐

  1. 小L的试卷

    题目描述 小L期末考试结束,高高兴兴放假回家了,可是那么多试卷,老师还要加班批改,有n份试卷由k个老师批改,n份试卷进行了密封编号,由于试卷上的做题情况和书写的规范程序不一样,批改不同的试卷用时也可能 ...

  2. 2017软工实践K班总结

    回首一学期的软工实践,从暑假开始陆续布置作业,经历个人.结对与团队等大小作业.也经历了不少同学被吓跑.第一周就退选的情况,能坚持下来的都是胜利者,至少你们有一颗愿意挑战的心.首先感谢助教谢涛付出的巨大 ...

  3. Telnet服务器和客户端请求处理

    Telnet服务器和客户端请求处理 本文的控制台项目是根据SuperSocket官方Telnet示例代码进行调试的,官方示例代码:Telnet示例. 开始我的第一个Telnet控制台项目之旅: 创建控 ...

  4. 单例模式及设计url分发

      1.单例模式 2.admin源码解析 3.注册源码流程图 3.admin之url方法的使用 4.admin源码之url设计 5.设计url源码流程 6.总结 1.单例模式 https://www. ...

  5. 【学习总结】GirlsInAI ML-diary day-5-布尔表达式/Bool

    [学习总结]GirlsInAI ML-diary 总 原博github链接-day5 认识布尔表达式 简单来说,bool 就是对错判断. 给个条件,如果满足条件就返回True, 不满足条件就返回Fal ...

  6. 封装day.js

    封装day.js import dayjs from 'dayjs' import 'dayjs/locale/zh-cn' import relativeTime from 'dayjs/plugi ...

  7. 转:VIM选择文本块/复制/粘贴

    VIM选择文本块/复制/粘贴 - lcj_cjfykx的专栏 - CSDN博客https://blog.csdn.net/lcj_cjfykx/article/details/9091569

  8. Rime 小狼毫 注意事项

    https://rime.im/https://github.com/rime/weasel/pulse 打不出中文可能是,没有五笔需要的文件: wubi_pinyin.schema.yamlCtrl ...

  9. 4 Past progressive VS simple past

    1 一般过去时用来谈论过去开始和结束的活动.过去进行时用来谈论过去正在进行或者发生的活动. Why were you at office so later yesterday? I was worki ...

  10. C++常用宏

    宏是由 #define 定义而来,在预处理阶段进行宏展开,它的格式是: #define N 2 + 2 // 仅仅是字符串替换 #define N (2 + 2) // 也是字符串 ,但是是(2 + ...