python单例模式的原理及实现

python单例模式的原理及实现

什么是单例模式:
单例模式即一个类有且仅有一个实例。

为什么要用:
全局变量,因为这比函数的参数传来传去更容易让人理解。确实在很多场景下用全局变量很方便。不过如果代码规模增大,并且有多个文件的时候,全局变量就会变得比较混乱。
你可能不知道在哪个文件中定义了相同类型甚至重名的全局变量,也不知道这个变量在程序的某个地方被做了怎样的操作。
单例模式保证了在程序的不同位置都可以且仅可以取到同一个对象实例:如果实例不存在,会创建一个实例;如果已存在就会返回这个实例。因为单例是一个类,所以你也可以为其提供相应的操作方法,以便于对这个实例进行管理。

python中,一个类创建对象实例是通过调用父类object的 __new__(cls)方法来创建对象的,因此我们可以通过重写 __new__(cls)方法去实现类只创建一个实例

class Sun(object):
__instance=None #定义一个类属性做判断
def __new__(cls):
if cls.__instance==None:
#如果__instance为空证明是第一次创建实例
#通过父类的__new__(cls)创建实例
cls.__instance==object.__new__(cls)
return cls.__instance
else:
#返回上一个对象的引用
return cls.__instance
a = Sun()
print(id(a))
b = Sun()
print(id(b))
使用函数装饰器实现单例
def singleton(cls):
_instance = {}

def inner():
if cls not in _instance:
_instance[cls] = cls()
return _instance[cls]
return inner

@singleton
class Cls(object):
def __init__(self):
pass

cls1 = Cls()
cls2 = Cls()
print(id(cls1) == id(cls2))
使用类装饰器实现单例

class Singleton(object):
def __init__(self, cls):
self._cls = cls
self._instance = {}
def __call__(self):
if self._cls not in self._instance:
self._instance[self._cls] = self._cls()
return self._instance[self._cls]

@Singleton
class Cls2(object):
def __init__(self):
pass

cls1 = Cls2()
cls2 = Cls2()
print(id(cls1) == id(cls2))

使用 metaclass 实现单例模式
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]

class Cls4(metaclass=Singleton):
pass

cls1 = Cls4()
cls2 = Cls4()
print(id(cls1) == id(cls2))

猜你喜欢

转载自www.cnblogs.com/tingxin/p/12197904.html