python手写单例模式_Python3 & 使用__new__实现单例模式

单例设计模式概念

设计模式,是对工作的总结和提练,目的是提高代码的可重用性及可靠性。

单例设计模式,是指让类创建的对象,在系统中只有 唯一的一个实例。且每一次执行 类名() 返回的对象,内存地址是相同的。这种模式一般应用在 例如:打印机,视频播放等应用上。

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)

输出结果:

初始化打印机对象....

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)

输出:

初始化打印机对象....

初始化打印机对象....

可以看出,在每次使用 类名() 创建对象时,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)

输出:

初始化打印机对象....

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值