基于 __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+属性名() ... 
随机推荐
- Flask入门的第一个项目进阶版
			前言: 此次版本增加[一对多]数据库关系和动态路由设置. 一.数据库设计 environments表与variable1表的关系为:一对多.variable1.env_id设置为外键,与environ ... 
- Python_查找员工信息-48
			''' 查找出userinfo文件中年龄大于22岁的员工姓名和年龄 1,Alex,22,13651054608,IT 2,Egon,23,13304320533,Tearcher 3,nezha,25 ... 
- Python_生成器函数进阶_39
			def generator(): print(123) content = yield 1 #content接收的是send传的值 print('=======',content) print(456 ... 
- 用友云开放平台之API网关
			本文介绍选择API网关应考虑的几方面内容,API网关在微服务框架中的作用,API网关如何选型,用友云开放平台的API网关可以做什么. 随着互联网的快速发展,当前已步入移动互联.物联网时代.企业内部系统 ... 
- tailf、tail -f、tail -F三者区别(转)
			tail -f 等同于--follow=descriptor,根据文件描述符进行追踪,当文件改名或被删除,追踪停止 tail -F 等同于--follow=name --retry,根 ... 
- jvm 虚拟机内存模型
			来源:https://blog.csdn.net/A_zhenzhen/article/details/77917991?locationNum=8&fps=1 https://blog ... 
- Java 线程的创建和启动
			Java 使用 Thread 类代表线程,所有的线程对象都必须是 Thread 类或其子类的实例.每个线程的作用是完成一定的任务,实际上就是执行一段程序流(一段顺序执行的代码). Java 使用线程执 ... 
- python学习笔记(11)--词云
			中分词库 jieba 词云 wordcloud import jieba import wordcloud f = open("新时代中国特色社会主义.txt", "r ... 
- memcach 命令行
			1. cmd上登录memcache # telnet 127.0.0.1 11211 2. 列出所有items stats items 3. 通过itemid获取key 接下来基于列出的i ... 
- vue自定義指令
			自定義指令可以允許代碼複用, 全局自定義指令 vue.directive('指令名',{鉤子函數:指令函數}) 局部自定義指令: vue({ directives:{指令名:{鉤子函數:指令函數} } ... 
