__new_实现单例
单例就是在一个类每次实例化的时候实际上返回的都是同一个实例. 而__new__方法刚好就是控制类的实例化的
class A(object):
def __new__(cls,*args, **kwargs):
if not hasattr(cls,'instance'):
cls.instance = super().__new__(cls)
return cls.instance
a1 = A()
a2=A()
a3=A()
print(id(a1),id(a2),id(a3))
97682096 97682096 97682096
构造出了同一个实例,但是可以多次__init__() 初始化 ,或者说是同一个实例,共享了实例变量self.status
class A(object):
def __new__(cls,*args,**kw):
if not hasattr(cls,'instance'):
cls.instance = super().__new__(cls) #object.__new__ 只能传cls,剩下的参数应该还是传到init()里了
return cls.instance
def __init__(self,status):
print('init status with %s'%status)
self.status = status
a1 = A(1)
print(a1.status) #尽管object.__new__的时候没有用到参数,但是还是传参到__init__中了.
a2=A(2)
a3=A(3)
print(id(a1),id(a2),id(a3))
print(a1.status)
init status with 1
1
init status with 2
init status with 3
97743200 97743200 97743200
3
但是, 多线程的时候, 在做if not hasattr(cls,'instance')判断的时候可能多个线程同时判断为true,就造出多个实例了.
所以需要加入同步锁. 参考解决例子xiaorui
单例模式 静态方法实现方式
class A:
__instance = None #这里必须要赋值才能存在
def __init__(self,name):
self.name=name
@staticmethod
def create_instance():
if not A.__instance: #必须用A.来引用
A.__instance = A("Adam")
return A.__instance
obj1 = A.create_instance()
obj2 = A.create_instance()
obj3 = A.create_instance()
obj4 = A.create_instance()
print(id(obj1),id(obj2),id(obj3),id(obj4))
97706952 97706952 97706952 97706952
装饰器实现.
把类包裹起来,如果已经存在实例,则返回原来的实例,否则创建新的. 还可以将所有单例都装进个list中
def singleton(*args,**kw):
instances = dict()
def wrapper(cls):
def inner():
if cls not in instances:
instances[cls]= cls(*args,**kw)
return instances[cls]
return inner
return wrapper
@singleton('Adam')
class A(object):
def __init__(self,name=None):
self.name = name
@singleton()
class B:
pass
a = A()
a2=A()
b=B()
b2=B()
print(a.name)
print(a is a2,b is b2)
Adam
True True
##