基于 __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+属性名() ...
随机推荐
- H5 62-浮动元素字围现象
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- C++类的描述
类的描述分为两个部分,public和private public可以用来定义函数,对类的对象进行操作,对于用户是可见的,是用户对对象操作的唯一手段. private部分用于定义函数和数据成员,这些函数 ...
- mysql安装设置mysql字符集utf8及修改密码
MySQL的下载,建议下载MySQL的解压缩版本 MySQL官网下载推荐别下最新版本的原因是因为很多之前用的jar包和工具类不兼容最新版本的 可以下5.多的和六点多的 这样的压缩包解压再配置就行了 安 ...
- iOS UICollectionView 在滚动时停在某个item位置上
方法一:实现UIScrollView的代理,然后实现下面这个方法 #pragma mark - UIScrollViewDelegate//预计出大概位置,经过精确定位获得准备位置- (void)sc ...
- MyBatis模糊查询不报错但查不出数据的一种解决方案
今天在用MyBatis写一个模糊查询的时候,程序没有报错,但查不出来数据,随即做了一个测试,部分代码如下: @Test public void findByNameTest() throws IOEx ...
- 什么是车辆识别代码(VIN)
车辆识别代码(VIN),VIN是英文Vehicle Identification Number(车辆识别码)的缩写.因为ASE标准规定:VIN码由17位字符组成,所以俗称十七位码.正确解读VIN码,对 ...
- 自己实现数据结构系列四---Queue
一.代码部分 1.定义接口: public interface Queue<E> { void enqueue(E e); E dequeue(); E getFront(); int g ...
- Mysql连接数、线程数、数据包
https://blog.csdn.net/qq_26545305/article/details/79675507
- CMD管道命令使用
Windows netstat 查看端口.进程占用 开始--运行--cmd 进入命令提示符 输入netstat -ano 即可看到所有连接的PID 之后在任务管理器中找到这个PID所对应的程序如果任务 ...
- 剑指offer(18)二叉搜索树的后续遍历
题目: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 思路: 以最后一个节点为根,从头往后找到第一个大于根 ...