基于 __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+属性名() ...
随机推荐
- vue及Eelement使用过程中遇到的一些问题
在做项目的过程中,目前主要遇到了以下几个问题: 一.样式问题 1.样式中使用scoped的问题: 主要表现在从一个页面跳到另一个页面时,第二个页面的样式不能正确显示,通过刷新才能恢复页面的预定样式. ...
- CPU-bound(计算密集型) 和I/O bound(I/O密集型)
概念 概念I/O系统,英文全称为“Input output system”,中文全称为“输入输出系统”,由输入输出控制系统和外围设备两部分组成,是计算机系统的重要组成部分.在计算机系统中,通常把处理器 ...
- myeclipse使用hibernate5框架load延迟装载对象报错_$$_javassist_0 cannot be cast to javassist.util.proxy.Proxy
jar包问题,将hibernate-core-5.0.12.Final.jar删除,换为hibernate-core-4.2.3.final.jar搞定.注意项目运行过后可能删不掉jar包,只需关闭m ...
- Java Core - 序列化和反序列化
把对象转换为字节序列的过程称为对象的序列化 把字节序列恢复成对象的过程称为对象的反序列化 一.对象的序列化的应用: 1.把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中. 2.在网络上传送对象 ...
- VMware虚拟机与Windows文件共享
开发中,我们经常的需求是这样的:我想再Windows中进行快捷开发,但是想在linux中运行,那么需要将文件方便在linux中管理,基本可以分成两种方式: 1. 使用网络工具:vmware_tool工 ...
- react插件包
react-scoped-style support ie8,ie8+,chrome,firefox,safari does not support css priority (just apply ...
- Oracle创建'数据库'三步走
--创建表空间 create tablespace waterboss datafile 'd:\waterboss.dbf' size 100m autoextend on next 10m; -- ...
- flutter-StatelessWidget与StatefulWidget
StatelessWidget和StatefulWidget是flutter的基础组件,日常开发中自定义Widget都是选择继承这两者之一. 两者的区别在于状态的改变,StatelessWidget面 ...
- 用Python来操作redis 以及在Django中使用redis
什么是Redis? Redis是一款开源的.高性能的键-值存储(key-value store).它常被称作是一款数据结构服务器(data structure server). Redis的键值可以包 ...
- python爬虫之多线程、多进程、GIL锁
背景: 我们知道多线程要比多进程效率更高,因为线程存在于进程之内,打开一个进程的话,首先需要开辟内存空间,占用内存空间比线程大.这样想也不怪,比如一个进程用10MB,开10个进程就得100MB的内存空 ...