这是看了林海峰老师讲解单例模型的实现方法的总结来与大家分享~
一、@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)'''
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)