单例设计模式概念
设计模式,是对工作的总结和提练,目的是提高代码的可重用性及可靠性。
单例设计模式,是指让类创建的对象,在系统中只有 唯一的一个实例。且每一次执行 类名() 返回的对象,内存地址是相同的。这种模式一般应用在 例如:打印机,视频播放等应用上。
new 方法
使用 类名() 创建对象时,Python 的解释器 首先 会 调用 new 方法为对象 分配空间。new 是一个 由 object 基类提供的 内置的静态方法,主要作用有两个:
- 在内存中为对象 分配空间
- 返回 对象的引用
示例:
class PrintPlayer(object):
def __new__(cls, *args, **kwargs):
print("__new__")
def __init__(self):
print("初始化打印机对象....")
prints = PrintPlayer()
print(prints)
输出结果:
__new__
None
可以看到,上述示例中,new没有返回对象的引用,所以在打印实例化对象时,返回了 None
正确的写法应该是
class PrintPlayer(object):
def __new__(cls, *args, **kwargs):
return super().__new__(cls)
def __init__(self):
print("初始化打印机对象....")
prints = PrintPlayer()
print(prints)
输出结果:
初始化打印机对象....
<__main__.PrintPlayer object at 0x000002329A47E7C0>
Python 中的单例模式
所谓单例,是让类在系统中创建唯一的一个实例,那么如何做到呢?
步骤分析:
1)定义一个 类属性,初始值是 None,用于记录 单例对象的引用
2)重写 new 方法
3)如果 类属性 is None,调用父类方法分配空间,并在类属性中记录结果
4)返回 类属性 中记录的 对象引用
代码:
class PrintPlayer(object):
instance = None
def __new__(cls, *args, **kwargs):
if cls.instance is None:
cls.instance = super().__new__(cls)
return cls.instance
def __init__(self):
print("初始化打印机对象....")
prints1 = PrintPlayer()
print(prints1)
prints2= PrintPlayer()
print(prints2)
输出:
初始化打印机对象....
<__main__.PrintPlayer object at 0x000002776F59E7C0>
初始化打印机对象....
<__main__.PrintPlayer object at 0x000002776F59E7C0>
可以看出,在每次使用 类名() 创建对象时,Python 的解释器都会自动调用两个方法:new 分配空间,init 对象初始化。所以实例化两次,会调用init方法两次初始化。
那么如何让 初始化动作 只被 执行一次呢?
解决方法:
1)定义一个类属性 init_flag 标记是否 执行过初始化动作,初始值为 False
2)在 init 方法中,判断 init_flag,如果为 False 就执行初始化动作
3)然后将 init_flag 设置为 True
这样,再次 自动 调用 init 方法时,初始化动作就不会被再次执行 了
代码:
class PrintPlayer(object):
instance = None
init_flag = False
def __new__(cls, *args, **kwargs):
if cls.instance is None:
cls.instance = super().__new__(cls)
return cls.instance
def __init__(self):
if not PrintPlayer.init_flag :
print("初始化打印机对象....")
PrintPlayer.init_flag = True
prints1 = PrintPlayer()
print(prints1)
prints2= PrintPlayer()
print(prints2)
输出:
初始化打印机对象....
<__main__.PrintPlayer object at 0x000001E8E23CE7C0>
<__main__.PrintPlayer object at 0x000001E8E23CE7C0>
网友评论