Python 中的单例模式
单例模式
单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。
比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 AppConfig 这样的类,我们希望在程序运行期间只存在一个实例对象。
在 Python 中,我们可以用多种方法来实现单例模式:
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 # 方式1 5 class Singleton(): 6 def __new__(cls, *args, **kwargs): 7 if not hasattr(cls,'_instance'): 8 orig = super(Singleton, cls) 9 cls._instance = orig.__new__(cls,*args,**kwargs) 10 return cls._instance 11 12 13 class MyClass(Singleton): 14 a=1 15 16 one = MyClass() 17 two = MyClass() 18 two.a = 3 19 print(one.a) 20 print(id(one)) 21 print(id(two)) 22 print('-------------------------------') 23 24 #方式2 25 class Borg(object): 26 _state = {} 27 def __new__(cls, *args, **kwargs): 28 ob = super(Borg, cls).__new__(cls, *args, **kwargs) 29 ob.__dict__ = cls._state 30 return ob 31 def __hash__(self): 32 return 1 33 def __eq__(self, other): 34 try: 35 return self.__dict__ is other.__dict__ 36 except: 37 return False 38 39 class MyClass2(Borg): 40 a = 1 41 42 a = MyClass2() 43 b = MyClass2() 44 c = MyClass2() 45 # a.a = 11 46 # b.a = 12 47 # c.a = 13 48 # print(a.a, b.a, c.a) 49 50 adict = {} 51 j = 0 52 for i in a, b, c: 53 adict[i] = j 54 j += 1 55 for i in a, b, c: 56 print(adict[i]) 57 58 print('-------------------------------') 59 60 # 方式3 当你编写一个类的时候,某种机制会使用类名字,基类元组,类字典来创建一个类对象。新型类中这种机制默认为type,而且这种机制是可编程的,称为元类__metaclass__ 61 class Singleton2(type): 62 def __init__(self,name,bases,class_dict): 63 super(Singleton2,self).__init__(name,bases,class_dict) 64 self._instance=None 65 def __call__(self, *args, **kwargs): 66 if self._instance is None: 67 self._instance= super(Singleton2, self).__call__(*args, **kwargs) 68 return self._instance 69 70 class A(object): 71 __metaclass__ = Singleton2 72 a = A() 73 b = A() 74 print(id(a), id(b)) 75 76 print('-------------------------------') 77 78 # 方法4 python并不会对sys.modules进行检查以确保他们是模块对象,我们利用这一点将模块绑定向一个类对象,而且以后都会绑定向同一个对象了 79 class _singleton(object): 80 class ConstError(TypeError): 81 pass 82 def __setattr__(self, key, value): 83 if key in self.__dict__: 84 raise self.ConstError 85 self.__dict__[key]=value 86 def __delattr__(self, item): 87 if item in self.__dict__: 88 raise self.ConstError 89 raise NameError 90 import sys 91 sys.modules[__name__] = _singleton()