问题复现
今天复习单例模式时,当用基于__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中实例化对象时,需要两步走。
- 调用
__new__方法,返回一个对象 - 调用
__init__方法, 对上一步返回的对象进行初始化
而我刚刚实现单例模式的方法只是修改了__new__方法,使其每次都返回同一个对象。
但是没有处理__init__方法,这就使得每次实例化对象时,都要运行一次__init__方法。
这可不就会每次都把对象的属性修改为最后一次实例化的参数了嘛。
本文通过一个具体的Python单例模式实现案例,详细解释了仅重写__new__方法而不处理__init__方法所带来的问题,即每次实例化都会更新对象属性。
1331

被折叠的 条评论
为什么被折叠?



