软件测试学习 之 Python 单例的实现

本文介绍了Python中实现单例模式的思路和方法,通过重写__new__方法确保类只有一个实例。同时,针对Python3.7.2环境下,如果类重写了__init__方法,需要适当调整以防止多次初始化。文中还提及Python2实现单例的差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现单例的大体思路都是内置一个实例对象作为类的属性,在创建对象时再给实例赋值,或者传递该实例的引用,

Python是通过重写类的__new__方法实现单例

JAVA实现单例时,会定义一个对外提供获取实例的方法

两者不太一样,需要注意

另外,
python中除了重写__new__方法提供唯一一个实例之外,

如果程序中重写了__init__方法,还要注意修改__init__方法以避免每次重复执行

笔者Python版本为3.7.2,实现单例的代码如下:

class MusicPlay:
    # 定义一个实例作为类的属性
    instance = None

    #  定义一个标记,记录是否执行过初始化动作
    init_flag = False

    def __new__(cls, *args, **kwargs):
        """ 创建对象时,new方法会被自动调用"""
        # super 与 super()
        # print(super, type(super),super.__class__.__name__)
        # print(super(), type(super()),super().__class__.__name__)
        # print(super is super())
        # print()
        # print(super.__doc__)
        # print()
        # print(super().__doc__)
        # print()

        # 判断类属性是否被实例化(初始化)
        if cls.instance is None:
            print("实例对象分配空间...")
            # 调用父类方法,为对象分配空间
            cls.instance = super().__new__(cls)

        # 返回类属性实例的引用
        return cls.instance

        # 也可以简写成
        # return super().__new__(cls)

    def __init__(self):

        # 初始化动作只执行一次
        # 如果执行过,直接返回
        if MusicPlay.init_flag:
            return

        print("实例对象初始化...")
        MusicPlay.init_flag = True


music_play1 = MusicPlay()
music_play2 = MusicPlay()
print("music_play1 is music_play2:", music_play1 is music_play2)
print(music_play1)
print(music_play2)

结果如下: 

实例对象分配空间...
实例对象初始化...
music_play1 is music_play2: True
<__main__.MusicPlay object at 0x0000000002139A90>
<__main__.MusicPlay object at 0x0000000002139A90>

网上也有关于Python2实现单例,稍有不同

class A(object):
    #用类属性用来标识是否是第一次创建对象
    __ins = None
    def __new__(cls):
        #如果是第一次创建对象就把该对象的引用保存到__ins内
        if cls.__ins == None:
             cls.__ins = object.__new__(cls)
             #返回第一次创建对象的引用
             return cls.__ins
        else:
             #返回上一次创建的对象的引用
              return cls.__ins
a = A()
b = A()
print (id(a))
print (id(b))

执行结果 

18991816
18991816

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值