python单例模式继承_python单例模式控制成只初始化一次,常规型的python单例模式在新式类和经典类中的区别。...

单例模式的写法非常多,但常规型的单例模式就是这样写的,各种代码可能略有差异,但核心就是要搞清楚类属性 实例属性,就很容易写出来,原理完全一模一样。

如下:

源码:

classA(object):def __new__(cls, *args, **kwargs):if not hasattr(cls, ‘__inst‘):print(‘执行new‘)

obj= super(A, cls).__new__(cls)

setattr(cls,‘__inst‘, obj)returnobjelse:return cls.__dict__[‘__inst‘]def __init__(self, x):print(‘执行init‘)

self.x=xif __name__ == ‘__main__‘:

a1= A(1)print(‘a1.x‘, a1.x)

a2= A(2)print(‘a2.x‘, a2.x)print(‘a1.x‘, a1.x)

a3= A.__new__(A)#a3.__init__(3) # a3 = A(3) 实际是调用了new和init方法,此处屏蔽调用init

print(‘a3.x‘, a3.x)print(id(a1), id(a2), id(a3))

实例化了三个对象,执行结果可以猜猜:

可以发现,执行了一次new,但执行了两次init,这是在新式类下运行的,python3默认是新式类,不管有没有继承object。

如果是python2,且不继承object,实际上是只会打印执行一次init。所以这是py2和py3的又一个区别,经典类和新式类区别非常多,新式类的反射方法也与经典类有些不同。但一般文章只说新式类和经典类的区别只是广度优先和深度优先,误导。

3、终极目标就是使python3的实例也不多执行力一次init,(因为虽然单例模式能控制成是所有类的实例指向同一个对象,但有时候的单例模式初始化是建立一个io连接或者资源池,这样每次执行初始化浪费一些时间)

两种方法,一种是增加一个类属性做标志,在init方法中增加if判断

第二种是,不使用 a = A(xxxx),而使用a = A.__new__(A),因为a = A(xxxx),实际上是a = A.__new__(A),和a.__init__(xxx)

4、还有一种方式是使用装饰器,如果按照这个写法也不会执行多次init

#coding=utf8

from functools importwrapsdefsingleton(cls):printcls

instances={}

@wraps(cls)def getinstance(*args, **kw):if cls not ininstances:

instances[cls]= cls(*args, **kw)returninstances[cls]returngetinstance

@singletonclassMyClass(object):

a= 1m1=MyClass()

m2=MyClass()print m1 is m2

原文:https://www.cnblogs.com/ydf0509/p/9463832.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值