单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。
__new__()
在__init__()
之前被调用,用于生成实例对象。利用这个方法和类的属性的特点可以实现设计模式的单例模式。单例模式是指创建唯一对象,单例模式设计的类只能实例化一次。
In [15]: class Singleton:
...: def __new__(cls, *args, **kwargs):
...: if not hasattr(cls, '_instance'):
...: cls._instance = super().__new__(cls, *args, **kwargs)
...: return cls._instance
...:
In [16]: class MyClass(Singleton):
...: a = 1
...:
In [17]: my_class1 = MyClass()
In [18]: my_class2 = MyClass()
In [19]:
In [19]: my_class1.a
Out[19]: 1
In [20]: my_class2.a
Out[20]: 1
In [21]: my_class1 is my_class2
Out[21]: True
上面使用__new__
来实现单例,下面我们使用元类来实现以下。
import threading
import traceback
class SingletonMetaclass(type):
def __init__(cls, name, bases, attrs):
cls._instance = None
cls._lock = threading.Lock()
def __call__(cls, *args, **kwargs):
result = None
cls._lock.acquire()
try:
if cls._instance is not None:
result = cls._instance
else:
result = cls._instance = super().__call__(*args, **kwargs)
except BaseException:
traceback.print_exc()
finally:
cls._lock.release()
return result
class Singleton(metaclass=SingletonMetaclass):
pass
In [23]: class MyClass(Singleton):
...: a = 1
...:
In [24]: my_class1 = MyClass()
In [25]: my_class2 = MyClass()
In [26]: my_class1.a
Out[26]: 1
In [27]: my_class2.a
Out[27]: 1
In [28]:
In [28]: my_class1 is my_class2
Out[28]: True
参考文章:
深刻理解Python中的元类(metaclass)以及元类实现单例模式
深入理解Python中的元类(metaclass)
网友评论