Python singleton pattern [detailed]: (concept, __new__ method concept and rewriting, singleton design pattern application scenarios, code implementation, only perform one initialization action)

python old bird 2022-09-23 08:04:24 阅读数:355

pythonsingletonpatterndetailedconcept

欢迎关注博主 python老鸟 或 前往 『Python自学网』, 从基础入门免费课程开始,逐步深入学习python全栈体系课程,适合新手入门到精通全栈开发.


免费专栏传送门:《Python基础教程

 


目录

一、Design patterns and singleton design pattern concepts

1)设计模式:

2)单例设计模式:

3)单例设计模式应用场景

二、__new__方法

1)使用类名()创建对象时,Python解释器做的2件事:

2)重写__new__方法的代码非常固定:

3)重写__new__Method code walkthrough

三、Python中的单例

1)Analysis of singleton design pattern ideas

2)实现单例设计模式——验证是否是同一个对象

四、The initialization method is executed only once


 

一、Design patterns and singleton design pattern concepts

1)设计模式:

含义:

设计模式是前人工作的总结和提炼,Often widely used design patterns are mature solutions to a specific problem.

作用:

使用设计模式是为了可重用代码,让代码更容易被他人理解,保证代码的可靠性.

 

2)单例设计模式:

目的:

  1. 让类创建的对象在系统中只有唯一的一个实例
  2. 每一次执行 类名() 返回的对象,内存地址是相同的

 

3)单例设计模式应用场景

场景:

音乐播放对象(Only one song can be played at a time)、

回收站对象(There is only one Recycle Bin on your computer)、

......

共同特点:

Both objects have only unique existence

 


 

二、__new__方法

__new__方法(newBefore and after the letters are two underscores in English,Methods that start with two underscores and end with two underscores are built-in methods)

 

1)使用类名()创建对象时,Python解释器做的2件事:

  1. 使用 类名() 创建对象时,Python解释器首先会调用__new__方法为对象分配空间
  2. Python的解释器获得对象的引用后,将引用作为第一个参数,传递给__init__方法

 

简单理解就是: The first thing is to allocate space for the object,The second thing is to initialize the object.

 

31b4dd1e826347709914408da1a9ade8.png

 

 

__new__是一个由object基类提供的内置的静态方法.

主要作用有2个:

  1. 在内存中为对象分配空间
  2. 返回对象的引用

 

2)重写__new__方法的代码非常固定:

  1. 重写__new__The method must return allocated spacereturn super().__new__(cls)
  2. 否则Python的解释器得不到分配了空间的对象引用,就不会调用对象的初始化方法

注意:

__new__是一个静态方法,在调用时需要主动传递cls参数

 

3)重写__new__Method code walkthrough

简单代码:

class MusicPlayer(object):
def __init__(self):
print("Player object initialization")
# 创建播放器对象
player = MusicPlayer()
print(player)

执行结果:

fdcbb4a425654a73bfebfc5dc310725c.png

 

重写object基类提供的__new__方法代码1:

class MusicPlayer(object):
def __new__(cls, *args, **kwargs):
# 1. 创建对象时,new方法会被自动调用
print("创建对象自动调用new方法,分配空间")
def __init__(self):
print("Player object initialization")
# 创建播放器对象
player = MusicPlayer()
print(player)

 

执行结果:

722c65321d9b441ca02cbecad929ea95.png

 

None:因为重写__new__The method did not return the allocated spacereturn super().__new__(cls),此时Python的解释器得不到分配了空间的对象引用,就不会调用对象的初始化方法.

 

重写object基类提供的__new__方法代码2(完整):

class MusicPlayer(object):
def __new__(cls, *args, **kwargs):
# 1. 创建对象时,new方法会被自动调用
print("创建对象自动调用new方法,分配空间")
# 2. 为对象分配空间
# super():父类方法
instance = super().__new__(cls)
# 3. 返回对象的引用
return instance
def __init__(self):
print("Player object initialization")
# 创建播放器对象
player = MusicPlayer()
print(player)

执行结果:

6136d93687bf4a929781df987f217f49.png

 


 

三、Python中的单例

1)Analysis of singleton design pattern ideas

单例 —— 让类创建的对象,在系统中只有唯一的一个实例(That is, no matter how many times an object is created using this class, it is the same object)

 

思路分析:

  1. Define the same class property,初始值是None用于记录单例对象的引用
  2. 重写__new__方法
  3. 如果类属性is None调用父类方法分配空间,并在类属性中记录结果
  4. 返回类属性中记录的对象引用

4f7a22c3a03d4f90b09f17d20d805aaf.png

 

 

2)实现单例设计模式——验证是否是同一个对象

1.验证前准备,Make sure it's not the same object at this time:

 

代码:

class MusicPlayer(object):
pass
# 创建多个对象,Check if the addresses are the same
player1 = MusicPlayer()
print(player1)
player2 = MusicPlayer()
print(player2)

 

执行结果:地址不同

387b782d6c4444aea6afbc8c248fc56f.png

2.Verify that the singleton design pattern is the same object:

代码:

class MusicPlayer(object):
# 记录第一个被创建对象的引用
instance = None
def __new__(cls, *args, **kwargs):
# 1. Determines whether a class property is an empty object,no empty object,Indicates that the first object has not been created yet
if cls.instance is None:
# 2. 调用父类的方法,为第一个对象分配空间
cls.instance = super().__new__(cls)
# 3. 返回类属性保存的对象引用
return cls.instance
# 创建多个对象,Check if the addresses are the same
player1 = MusicPlayer()
print(player1)
player2 = MusicPlayer()
print(player2)

执行结果:地址相同,Prove that the two pairs of correlations are essentially the same object

68aa89ec6c2e46479469a3d9372ab687.png

 


 

四、The initialization method is executed only once

 

在每次使用类名() 创建对象时,PythonThe interpreter automatically calls both methods:

  1. __new__  分配空间
  2. __init__  对象初始化

The code above is right__new__方法改造之后,Each time you get a reference to the first created object,But the initialization method will still be called again.

--------------------------------------------------------------------------------------------------------

 

需求:让初始化动作只被执行一次.

解决办法:

  1. 定义一个类属性init_flag标记是否执行过初始化动作,初始值为False
  2. 在__init__方法中判断init_flag,如果为False就执行初始化动作
  3. 然后将init_flag设置为True,这样再次调用__init__方法时,初始化动作就不会被再次执行了

 

1.Preparation before code implementation,创建了两次对象,The initialization method is executed twice:如图

e6a9ef8746574d88a07e1b5a1b8b9a33.png

2.Code where the initialization action is executed only once:

class MusicPlayer(object):
# 记录第一个被创建对象的引用
instance = None
# Records whether to perform initialization actions
init_flag = False
def __new__(cls, *args, **kwargs):
# 1. Determines whether a class property is an empty object,no empty object,Indicates that the first object has not been created yet
if cls.instance is None:
# 2. 调用父类的方法,为第一个对象分配空间
cls.instance = super().__new__(cls)
# 3. 返回类属性保存的对象引用
return cls.instance
def __init__(self):
# 1. 判断是否执行过初始化动作
if MusicPlayer.init_flag:
return
# 2. 如果没有被执行过,再执行初始化动作
print("初始化方法执行")
# 3. 修改类属性init_flag的值为True
MusicPlayer.init_flag = True
# 创建多个对象,Check if the addresses are the same
player1 = MusicPlayer()
print(player1)
player2 = MusicPlayer()
print(player2)

增加代码:

47658a1462704b048b5ba04275783700.png

 

执行结果:

fa9c1b18fc79429d9616a0f1823a0b0d.png

 

 

 

 

 

copyright:author[python old bird],Please bring the original link to reprint, thank you. https://en.javamana.com/2022/266/202209230724062154.html