实现Python单例模式时发现的一个小问题

本文通过一个具体的Python单例模式实现案例,详细解释了仅重写__new__方法而不处理__init__方法所带来的问题,即每次实例化都会更新对象属性。

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

问题复现

今天复习单例模式时,当用基于__new__方法实现时,遇到过小问题。
代码如下:

from threading import Lock


class Signleton(object):
    _signleton_lock = Lock()

    def __init__(self, a, curr='a'):
        self.a = a
        self.curr = curr

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            with Signleton._signleton_lock:
                if not hasattr(cls, '_instance'):
                    cls._instance = object.__new__(cls)
        return cls._instance

    def prove(self):
        print('id = %d, a = %d, curr = %s' % (id(self), self.a, self.curr))


if __name__ == '__main__':
    t1 = Signleton(2, 'b')
    t2 = Signleton(7, 'c')
    print(t1.prove() == t2.prove())

运行结果:

id = 140094976669456, a = 7, curr = c
id = 140094976669456, a = 7, curr = c
True

可以看到这个方法确实实现了单例模式。
但有个问题,实例的属性被修改为最后一次实例化时传入的参数了。
一开始有点不理解。直接上手调试了一下,才晓得问题出在哪。

问题解释

python中实例化对象时,需要两步走。

  1. 调用__new__方法,返回一个对象
  2. 调用__init__方法, 对上一步返回的对象进行初始化

而我刚刚实现单例模式的方法只是修改了__new__方法,使其每次都返回同一个对象。
但是没有处理__init__方法,这就使得每次实例化对象时,都要运行一次__init__方法。
这可不就会每次都把对象的属性修改为最后一次实例化的参数了嘛。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值