单例设计模式 | 学习笔记

简介: 快速学习单例设计模式

开发者学堂课程【Python 入门 2020年版:单例设计模式】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/639/detail/10383


单例设计模式

单例设计模式

单例设计模式是保证在全局里只有一个对象,例如在电脑的操作系统里只有一个回收站。

image.png

class Singleton(object) :

def _new__(cls,*args,**kwargs):

pass

def __init__(self, a, b):

self.a = a

self.b = b

# 调用 _new_ 方法申请内存

# 如果不重写 _new_ 方法,会调用 object 的 _new_ 方法

# object 的 _new_ 方法会申请内存

# 如果重写了 _new_ 方法,需要自己手动的申请内存

s1 = singleton(‘呵呵’,’嘿嘿嘿‘)

s2 = Singleton(‘哈哈‘,‘嘻嘻嘻’)

print(s1 is s2)  # True

创建两个对象 s1、s2,打印 ‘s1 is s2’ 发现结果是 False,单例的目的就是通过一些代码把 false 变成 true。

对象会首先调用 __new__ 方法申请内存然后再调用 __init__ 方法向内存中填入数据,s1、s2 调用方法时会同时申请内存,但他们申请的内存地址是不一样的,如果想要 s1、s2 申请的内存地址相同应该只允许 __new__ 方法被调用一次。

现在如果直接打印 s1、s2 结果会显示他们都是 none,如果不重写 __new__ 方法,会调用 object 的  __new__  方法,object 的 new 方法会申请内存,如果重写了 new 方法,需要自己手动的中请内存。

class singleton(object): 

def _new_(cls,*args,**kwargs ):

# 内存只需创建一个对象,并把对象的类型设置为 cls

cls.instance = object._new__(cls)

return cls.instance

def __init_(self, a, b):

self.a = a

self.b = b

# 调用 _new_ 方法申请内存

# 如果不重写 _new_ 方法,会调用 object  的 _new_ 方法

# object的 _new_ 方法会申请内存

# 如果重写了_new_方法,需要自己手动的申请内存

s1 = singleton(‘呵呵‘,‘嘿嘿嘿’)

s2 = singleton(‘哈哈’,‘嘻嘻嘻’)

print(type(s1)) 

在 python 里申请内存只需创建一个对象,并把对象的类型设置为 cls,这时打印 print(type(s1)) 就可以得到一个结果了。

class singleton:

instance = Nohe  # 类属性

@classmethod

def _new_(cls,*args,**kwargs ):

if cls.instance is None:

# 申请内存,创建一个对象,并把对象的类型设置为

cls.instance = object.__new__(cls)

return cls.instance

def _init__(self, a, b):

self.a = a

self.b = b

s1 = singleton(‘呵呵’,‘嘿嘿嘿‘)

s2 = singleton(‘哈哈‘,‘嘻嘻嘻‘)

print(s1 is s2)  # True

现在 s1 和 s2 依然不是一个对象,因为 s1、s2 都需要调用 __new__ 方法都会创建一个新的地址,现在只需要判断一下让他们只调用一次即可。在每一次创建对象时判断类对象是否为空,如果为空申请内存并且把类对象进行赋值,最后返回。

现在 s1、s2 就变成了一个对象了。

class singleton:

instance = Nohe  # 类属性

@classmethod

def _new_(cls,*args,**kwargs ):

if cls.instance is None:

# 申请内存,创建一个对象,并把对象的类型设置为

cls.instance = object.__new__(cls)

return cls.instance

def _init__(self, a, b):

self.a = a

self.b = b

s1 = singleton(‘呵呵‘,‘嘿嘿嘿’)

s2 = singleton(‘哈哈‘,‘嘻嘻嘻‘)

print(s1.a == s2.a)

print(s1.b == s2.b)]

print(s1.a, s1.b)、

image.png

打印 s1 的 a、s2 的 a 和 s1 的 b、s2 的 b 发现他们是相等的,因为他们指向同一块内存。打印 s1 的 a 和 s2 的 b 的结果是‘哈哈’、‘嘻嘻嘻’,发现 s2 把 s1 覆盖了。

s2 创建的时候没有创建成功,在运行 __new__ 之后紧接着运行 __init__ 他直接进入了__init__代码把‘嘿嘿’改成了‘哈哈’,把‘嘿嘿嘿’改成了‘嘻嘻嘻’。

class singleton:

instance = Nohe  # 类属性

__is_first = True

@classmethod

def _new_(cls,*args,**kwargs ):

if cls.instance is None:

#申请内存,创建一个对象,并把对象的类型设置为

cls.instance = object.__new__(cls)

return cls.instance

def _init__(self, a, b):

if self.__is_first:

self.a = a

self.b = b

self.__is_first = False

s1 = singleton(‘呵呵‘,‘嘿嘿嘿‘)

s2 = singleton(‘哈哈’,‘嘻嘻嘻’)

s3 = singleton(‘嗄嗄‘,‘嘤嘤嘤‘)

再创建一个 s3 会发现结果变成了 s3 的内容,因为他再次运行了__init__ 。

例如在操作系统里再创建了一个回收站,虽然没有创建成功但是他改

变了回收站的属性,第一次创建的对象就相当于没被创建。想要第一

个对象不被后面的对象替换,只需再添加一个判断即可。

image.png 

S = singleton 每一次都会调用 __init__ 方法,__init__ 内存空间里只有 a 属性和 b属性没有 __is_first 属性,所以他会向上找到 __is_first 。

因为类属性只能通过类对象来修改所以之后self.__is_first = False 会在 __init__ 里加入一个 __is_first = False。

相关文章
|
7月前
|
设计模式
单例设计模式步骤
单例设计模式步骤
35 1
|
7月前
|
设计模式 安全 测试技术
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
147 0
|
7月前
|
设计模式 安全 Java
【设计模式】2、设计模式分类和单例设计模式
【设计模式】2、设计模式分类和单例设计模式
59 0
|
7月前
|
设计模式 Java
26、Java 简单实现单例设计模式(饿汉式和懒汉式)
26、Java 简单实现单例设计模式(饿汉式和懒汉式)
58 2
|
7月前
|
设计模式 安全 Java
在Java中即指单例设计模式
在Java中即指单例设计模式
41 0
|
19天前
|
设计模式 前端开发 JavaScript
JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
24 2
|
2月前
|
设计模式 Java Kotlin
Kotlin学习笔记 - 改良设计模式 - 迭代器模式
Kotlin学习笔记 - 改良设计模式 - 迭代器模式
29 2
|
3月前
|
设计模式 存储 安全
设计模式——设计模式介绍和单例设计模式
饿汉式(静态常量)、饿汉式(静态代码块)、懒汉式(线程不安全)、懒汉式(线程安全,同步方法)、懒汉式(线程不安全,同步代码块)、双重检查(推荐,线程安全、懒加载)、静态内部类(推荐)、枚举(推荐)
设计模式——设计模式介绍和单例设计模式
|
2月前
|
设计模式 JavaScript Scala
Kotlin学习笔记 - 改良设计模式 - 责任链模式
Kotlin学习笔记 - 改良设计模式 - 责任链模式
44 0
|
2月前
|
设计模式 Java Kotlin
Kotlin 学习笔记- 改良设计模式 - 装饰者模式
Kotlin 学习笔记- 改良设计模式 - 装饰者模式
27 0