相信大家学过编程语言对单例模式应该都很熟悉吧。今天就说一下在Python 中单例模式的写法。
1. 使用 __new__ 方式
1 class mySingleton(): 2 def __new__(cls, *args, **kwargs): 3 if not hasattr(cls, '_instance'): 4 cls._instance = super().__new__(cls, *args, **kwargs) 5 return cls._instance 6 7 8 ms1 = mySingleton() 9 ms2 = mySingleton() 10 print(id(ms1) == id(ms2))
>>> True
2. 装饰器
1 def singleton_decorate(func): 2 intance_dict = {} 3 4 def get_instance(*args, **kwargs): 5 # if not intance_dict: 6 if "instance" not in intance_dict: 7 intance_dict["instance"] = func() 8 return intance_dict["instance"] 9 10 return get_instance 11 12 13 @singleton_decorate 14 class singleton(): 15 pass 16 17 18 s1 = singleton() 19 s2 = singleton() 20 print(id(s1) == id(s2))
3. 元类
1 class Singleton(type): 2 instance = {} 3 4 def __call__(cls, *args, **kwargs): 5 if "instance" not in cls.instance: 6 cls.instance["instance"] = super().__call__(*args, **kwargs) 7 return cls.instance["instance"] 8 9 10 class myCls(metaclass=Singleton): 11 pass 12 13 14 mc1 = myCls() 15 mc2 = myCls() 16 print(id(mc1) == id(mc2))
这是三种创建单例模式的方法。只是扩展一下。代码之中用到了 __new__, __call__ 方法,其中还有 __init__ 方法,他们的作用是什么?
__new__:
对象的创建会调用这个方法, 它是一个静态方法返回一个类对象, 默认情况下是不需要写的,可以 overide。
__init__:
说 __new__ 就必须说 __init__ 方法, 因为 __new__ 是创建对象,但是并没有对对象进行初始化,而 __init__ 作用便是初始化对象, 加载对象数据, 也可以 overide。
__call__ :
我现阶段了解的 __call__ 方法是, 类可以调用, 就是 a = A() , A() 是生成对象,那 a() 这么呢, 如果有 __call__ 方法的话, a() 就是调用 __call__ 方法。
上面代码中 myCls 就是 Singleton 的对象,因为 myCls 的元类是 Singleton ,在这里解释一下元类吧。
元类:
我们都知道 类实例 是 类 的对象, 那么 类 又是谁的对象呢?答案就是:元类, 元类的对象便是类,所以上面 元类这种单例模式就很好解释了。
ps: 今天就和大家分享到这里,如有不对,还请指正,谢谢。
共勉!