设计模式-单例-Python实现
单例是什么?
【设计模式-单例-Python实现】单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。简单来说,就是某种类,它有且就有一个实例。
维基百科-单例模式
在Python中怎么实现 重写
__new__
方法
__new__
是类在创建时(不是实例化)时会调用的成员方法,其参数是这个类本身,即cls
。这里我们使用hasattr
方法来判断一个类有没有实例。如果没有就新建一个,有的话就返回当前的那个。这样就保证了这个类永远只会有一个实例。# singleton
class Singleton(object):
def __new__(cls):
if not hasattr(cls, '_instance'):
cls._instance = super(Singleton, cls).__new__(cls)
return cls._instanceclass MyClass(Singleton):
a = 1A = MyClass()
B = MyClass()print (A is B)
装饰器实现 这个方法的核心思想就是将对象的实例用其他的容器保存下来,每次实例类的时候,装饰器会判断这个类是不是已经在容器中了。如果是,则直接返回容器中的实例,否则则新建一个实例返回并放入容器中。容器中最多只会有一个值。
# singleton
def singleton(cls):
instances = {}
def getinstance(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return getinstance@singleton
class MyClass():
a = 1A = MyClass()
B = MyClass()print (A is B)
用list 也可以
# singleton
def singleton(cls):
instances = []
def getinstance(*args, **kwargs):
if not instances:
instances.append(cls(*args, **kwargs))
return instances[0]
return getinstance@singleton
class MyClass():
a = 1A = MyClass()
B = MyClass()#print (len(A))
print (A is B)
这样也可以
# singleton
instances = None
def singleton(cls):
def getinstance(*args, **kwargs):
global instances
if not instances:
instances = cls(*args, **kwargs)
return instances
return getinstance@singleton
class MyClass():
a = 1A = MyClass()
B = MyClass()#print (len(A))
print (A is B)
但是这样不行
# singleton
def singleton(cls):
instance = None
def getinstance(*args, **kwargs):
if not instance:
instance = cls(*args, **kwargs)
return instance
return getinstance@singleton
class MyClass():
a = 1A = MyClass()
B = MyClass()#print (len(A))
print (A is B)
为什么?因为这里构成了闭包,Python只会会把闭包中用到的值保存下来,但是你不能在闭包中对其进行修改。也就是说在这个例子里,你只能访问
instance
,但是不能对其赋值,否则会报错UnboundLocalError
。我会在另外一篇关于作用域和闭包的文章中仔细讲一讲。怎么改呢?一种就是用上面的两种方法,将它改成一个列表或者字典,我们不能对列表本身做修改,但是可以对列表中包含的对象做修改;另一种方法则是用关键词nonlocal:
# singleton
def singleton(cls):
instance = None
def getinstance(*args, **kwargs):
nonlocal instance
if not instance:
instance = cls(*args, **kwargs)
return instance
return getinstance@singleton
class MyClass():
a = 1A = MyClass()
B = MyClass()#print (len(A))
print (A is B)
推荐阅读
- 设计模式-代理模式-Proxy
- 设计模式【15】--从审批流中学习责任链模式
- GCD小总结
- 14--Python|14--Python 面向对象进阶
- 2020-11-18迭代器设计模式
- 类的加载过程
- OpenCV|OpenCV-Python实战(18)——深度学习简介与入门示例
- 回归|金融数值方法之回归计算-python实践
- 设计模式(6)|设计模式(6) : 原型模式
- SpringBean单例情况下解决循环依赖的原理