三种单例模式
python面试中一般会问到单例模式,下面介绍一下常见的3种python单例模式
第一种 __new__方法
class Foo(object): def __init__(self,name): self.name = name def __new__(cls, *args, **kwargs): if not hasattr(cls,'_instance'): cls._instance = object.__new__(cls) return cls._instance # def __new__(cls, *args, **kwargs): # if not hasattr(cls, '_instance'): # cls._instance = super(Foo, cls).__new__(cls) # return cls._instance f1= Foo('alex') print(f1.name,f1) # alex <__main__.Foo object at 0x0000000002249630> f2= Foo('egon') print(f2.name,f2) # egon <__main__.Foo object at 0x0000000002249630> print(f1 is f2) # True # 反例 class Foo(object): def __init__(self,name): self.name = name f3= Foo('alex') print(f3.name,f3) # alex <__main__.Foo object at 0x000000000215B4E0> f4= Foo('egon') print(f4.name,f4) # egon <__main__.Foo object at 0x0000000002AAF0B8> print(f3 is f4) # False
第二种 自定义classmethod方法
class Foo: _instance = None def __init__(self, name): self.name = name @classmethod def get_instance(cls, name): # 类方法, 第一个参数默认是类这个对象 if cls._instance: # 判断如果这个静态字段为真(已经存在实例) cls._instance.name=name # 重新给name赋值 return cls._instance # 直接返回这个实例 else: # 如果实例不存在 obj = cls(name) # 在类的内部创建一个实例,内部调用了init构造方法 cls._instance = obj # 将该实例赋值给类的静态字段,防止下次重复创建 return obj # 将新创建的对象返回 # 经过上面的修改, 如果想实现单例模式, 就不能再使用init构造方法来创建对象了 # f1= Foo('alex') # print(f1.name,f1) # alex <__main__.Foo object at 0x0000000002289A90> # # f2= Foo('egon') # print(f2.name,f2) # egon <__main__.Foo object at 0x00000000027B95C0> # # print(f1 is f2) # False # 而是通过类方法创建 f3 = Foo.get_instance("alex") # 第一次会创建对象 print(f3.name,f3) # alex <__main__.Foo object at 0x0000000002A9F0B8> f4 = Foo.get_instance("egon") # 第二次会使用第一次创建的对象 print(f4.name,f4) # egon <__main__.Foo object at 0x0000000002A9F0B8> print(f3 is f4) # True
第三种 import方法
# mysingleton.py class My_Singleton(object): def foo(self): pass my_singleton = My_Singleton() # to use from mysingleton import my_singleton my_singleton.foo()