这是看了林海峰老师讲解单例模型的实现方法的总结来与大家分享~
一、@classmethod ->通过类方法实现
'''class Foo:
# 定义一个类的数据属性,用于接收对象的实例,判断对象是否只有一个
_instance = None
def __init__(self, name, age):
self.name = name
self.age = age
@classmethod
def singlenton(cls, *args, **kwargs):
# 判断类属性_instance是否有值,有-》代表已经有实例对象
# 没有则代表没有实例对象,则调用object.__new__获取一个空对象
if not cls._instance:
# 没有参数的情况下
# cls._instance=object.__new__(cls,*args,**kwargs)
# 有参数的情况下:
cls._instance = cls(*args, **kwargs) # 等价于Foo(*args, **kwargs) ->cls==Foo
# 将已经产生的实例化对象直接返回
return cls._instance
obj1 = Foo.singlenton('egon', 20)
obj2 = Foo.singlenton('tank', 19)
print(obj1 is obj2)'''
二、元类实现
'''class MyMeta(type):
def __init__(self,name,base,attrs):# self->Goo
# 造空对象,然后赋值给Goo类中的_instance类属性
self._instance=object.__new__(self)
# 将类名、基类、类的名称空间传给type里面的__init__
super().__init__(name, base, attrs)
# 当调用Goo类时,等同于调用元类实例化得到的对象
def __call__(self, *args, **kwargs):
# 判断调用Goo时是否传参
if args or kwargs:
init_args=args
init_kwargs=kwargs
# 1、通过判断限制了用于传入的参数必须一致,然后返回一个实例化对象
if init_args==args and init_kwargs==kwargs:
return self._instance
# 2、若不是一个实例,则创建一个新对象,产生新的内存地址
obj=object.__new__(self)
self.__init__(obj,*args, **kwargs)
return obj
return self._instance
class Goo(metaclass=MyMeta):# Goo=MyMeta(Goo)
def __init__(self,x):
self.x=x
g1=Goo('1')
g2=Goo('2')
print(g1 is g2)'''
三、__new__实现 --》通过调用类方法实例化对象时,自动触发的__new__来实现单例
'''class Aoo:
_instance=None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance=object.__new__(cls)
return cls._instance
a1=Aoo()
a2=Aoo()
print(a1 is a2)'''
四、装饰器
'''def singlenton(cls):# cls-->Too
# 因为装饰器可以给多个类使用所以这里采用字典
# 以类为key,实例对象作为value值
_instance={
# "Too":Too的实例对象
}
def inner(*args,**kwargs):
# 若当前装饰器的类不在字典中,则实例化新类
if cls not in _instance:
# obj=cls(*args,**kwargs)
# return obj
# 不在,则给字典添加key为Too,value为Too()-->实例对象
#{Too:Too(*args,**kwargs)}
_instance[cls] = cls(*args, *kwargs)
#return 对应的实例化对象 cls(*args,*kwargs)
return _instance[cls]
return inner
@singlenton# -->singlenton(Too)
class Too:
pass
t1=Too()
t2=Too()
print(t1 is t2)'''