单例模式
相信大家都知道单例模式
单例模式最初的定义出现于《设计模式》(艾迪生维斯理, 1994):“保证一个类仅有一个实例,并提供一个访问它的全局访问点。”
单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。
那么,为什么不直接使用全局变量,而要搞一个单例出来?单例到底比全局变量好在哪儿?
首先,全局变量不能保证全局只有一个类的实例,你完全可以声明同一个类的多个实例。当然,如果你注意一点,那么用全局方法保证全局只有一个该类的实例还是可以做到的,但你得很注意,让自己不要在其他地方声明多一个实例。而单例却可以轻松的做到这一点,并能保证全局只有一个该类的实例可被访问。
其次,相对来说,使用单例时,代码会显得优雅一些。
什么时候用单例
单例的使用主要是在需要保证全局只有一个实例可以被访问的情况,比如系统日志的输出、操作系统的任务管理器等。
一、使用new方法
class Singleton(object):
def __new__(cls, *args, **kw):
if not hasattr(cls, '_instance'):
orig = super(Singleton, cls)
cls._instance = orig.__new__(cls, *args, **kw)
return cls._instance
class MyClass(Singleton):
a = 1
二、共享属性
class Borg(object):
_state = {}
def __new__(cls, *args, **kw):
ob = super(Borg, cls).__new__(cls, *args, **kw)
ob.__dict__ = cls._state
return ob
class MyClass2(Borg):
a = 1
创建实例时把所有实例的dict指向同一个字典,这样它们具有相同的属性和方法.
三、装饰器版本
def singleton(cls, *args, **kw):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls(*args, **kw)
return instances[cls]
return getinstance
@singleton
class MyClass:
四、import方法
作为python的模块是天然的单例模式
# mysingleton.py
class My_Singleton(object):
def foo(self):
pass
my_singleton = My_Singleton()
# to use
from mysingleton import my_singleton
my_singleton.foo()
五、使用元类方法
class Singleton2(type):
def __init__(self, *args, **kwargs):
self.__instance = None
super(Singleton2,self).__init__(*args, **kwargs)
def __call__(self, *args, **kwargs):
if self.__instance is None:
self.__instance = super(Singleton2,self).__call__(*args, **kwargs)
return self.__instance
class Foo(object):
__metaclass__ = Singleton2 #在代码执行到这里的时候,元类中的__new__方法和__init__方法其实已经被执行了,而不是在Foo实例化的时候执行。且仅会执行一次。
foo1 = Foo()
foo2 = Foo()
print (Foo.__dict__) #_Singleton__instance': <__main__.Foo object at 0x100c52f10> 存在一个私有属性来保存属性,而不会污染Foo类(其实还是会污染,只是无法直接通过__instance属性访问)
print (foo1 is foo2) # True
网友评论