基于 __new__ 方法的单例模式
单例模式定义
首次实例化创建实例化对象
之后的每次实例化都用最初的实例化对象 即单实例模式
__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__ 方法的单例模式的更多相关文章
- python学习-(__new__方法和单例模式)
class Dog(object): __instance = None __init_flag = False def __new__(cls, name): if cls.__instance = ...
- python 单例模式,一个类只能生成唯一的一个实例,重写__new__方法详解
单例:一个类只能生成唯一的一个实例 每个类只要被实例化了,他的私有属性 '_instance'就会被赋值,这样理解对吗 对 #方法1,实现__new__方法 #并在将一个类的实例绑定到类变量_inst ...
- 详解python中的__init__与__new__方法
一.__init__和__new__方法执行的顺序? 在面向对象中介绍了关于对象创建的过程,我们知道__new__方法先于__init__方法执行. 二.__new__方法是什么? 首先,我们先来看下 ...
- python 中的__new__方法
1.有关__new__方法的介绍 __new__方法调用在构造方法构造实例之前,即在__init__方法执行之前,我们可以这样理解,他的作用是决定是否适用这个__iint__方法来构造实例,但是需要注 ...
- Python构造方法、析构方法和单例模式
一.__init__()方法 __init__()通常在初始化一个类实例的时候调用,如: class Student(object): def __init__(self,name,age): sel ...
- python面向对象之__new__方法
众所周知,python中定义的类在创建实例对象的时候,会自动执行__init__()方法,但是在执行__init__()方法之前,会执行__new__()方法. __new__()的作用主要有两个. ...
- python使用__new__创建一个单例模式(单例对象)
#单例模式:使一个类只产生一个对象.他们的id地址都指向同一个内存地址 第一步:理解谁创建了对象 # 单例模式# 首先明白,我们在创建一个类的对象的时候,其实是调用的这个类的父类,即继承object, ...
- day20-双下new方法,单例模式
# 1. __new__:构造方法,它创造对象,程序员口头语:new一个对象.先执行__new__方法再执行___init__方法. class Goods: def __init__(self):# ...
- Spring-Context之六:基于Setter方法进行依赖注入
上文讲了基于构造器进行依赖注入,这里讲解基于Setter方法进行注入.在Java世界中有个约定(Convention),那就是属性的设置和获取的方法名一般是:set+属性名(参数)及get+属性名() ...
随机推荐
- 广播频道-BroadcastChannel
BroadcastChannel,就字面意思来言,叫做“广播频道”,官方文档说,该API是用于同源不同页面之间完成通信的功能. 1. 概况 它与window.postMessage的区别就是,Broa ...
- BFC 原理
BFC:Block-level box + Forating + Context; ------->块元素 决定其子元素如何定位, ...
- 最短路问题 Floyd+Dijkstra+SPFA
参考博客:https://blog.csdn.net/qq_35644234/article/details/60875818 题目来源:http://acm.hdu.edu.cn/showprobl ...
- Mysql MyISAM与InnoDB 表锁行锁以及分库分表优化
一. 两种存储引擎:MyISAM与InnoDB 区别与作用 1. count运算上的区别: 因为MyISAM缓存有表meta-data(行数等),因此在做COUNT(*)时对于一个结构很好的查询是不需 ...
- MySQL数据库导入错误:ERROR 1064 (42000) 和 ERROR at line xx:
https://www.cnblogs.com/yeahgis/p/4358973.html mysql -hlocalhost -uroot -proot --default-character-s ...
- [转帖]Docker的数据管理(volume/bind mount/tmpfs)
Docker(十五)-Docker的数据管理(volume/bind mount/tmpfs) https://www.cnblogs.com/zhuochong/p/10069719.html do ...
- mybtis逆向工程实战教程--条件查询
mabitis逆向工程进行条件查询:
- Lodop获取全部JS代码,传统JS模版的生成
Lodop模版有两种方法,一种是传统的JS语句,可以用JS方法里的eval来执行,一种是文档式模版,是特殊格式的base64码,此篇博文介绍传统JS模版的生成方法.两种模版都可以存入一下地方进行调用, ...
- mesh函数
[t,W]=meshgrid([2:0.2:7],[0:pi/6:3*pi]); %设置时-频相平面网格点 Gs1=(1/(sqrt(2*pi)*a))*exp(-0.5*abs((t1-t)/a). ...
- codeforces467C
George and Job CodeForces - 467C The new ITone 6 has been released recently and George got really ke ...