单例模式(Singleton Pattern)是一种经常使用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。html
如,某个服务器程序的配置信息存放在一个文件中,客户端经过一个 Config 的类来读取配置文件的信息。若是在程序运行期间,有不少地方都须要使用配置文件的内容,也就是说,不少地方都须要建立 Config 对象的实例,这就致使系统中存在多个 Config 的实例对象,而这样会严重浪费内存资源,尤为是在配置文件内容不少的状况下。事实上,相似 Config 这样的类,咱们但愿在程序运行期间只存在一个实例对象。python
经过python的闭包原理,装饰器能记得外层命名空间装饰器原理参考本文数据库
def single_decorator(cls): single = {} def wrapper(*args, **kwargs): if not single.get(cls.__name__): single[cls.__name__] = cls(*args, **kwargs) return single[cls.__name__] return wrapper @single_decorator class School: def __init__(self, name, addr, capital, represent): self.__name = name #学校名 self.__addr = addr #地址 self.__registered_capital = capital #注册资金 self.__represent = represent #法人表明 def get_info(self): return "校名: {} 地址: {} 法人表明: {}".format(self.__name, self.__addr, self.__represent) @staticmethod def show(): print(School._isxx) ss= School('古天乐学校', '大凉山', '100.000', '古天乐') ss2= School('施明德', '台湾?', '1.000.000', '瞎写的') print('实例一id: %s'%(id(ss))) print('实例二id: %s'%(id(ss2))) print(ss.get_info()) print(ss2.get_info()) #运行结果为: 实例一id: 397109139440 实例二id: 397109139440 校名: 古天乐学校 地址: 大凉山 法人表明: 古天乐 校名: 古天乐学校 地址: 大凉山 法人表明: 古天乐
这样就能够将这个装饰器装饰到任何一个类上,完成单列了设计模式
class Single: _single = None def __init__(self, value): self.v = value print(self.v) def __new__(cls, *args, **kwargs): if Single._single: return Single._single else: Single._single = super(Single, cls).__new__(cls) print("只执行一次") return Single._single s2 = Single(2) s3 = Single(3) s4 = Single(4) print(id(s2)) print(id(s3)) print(id(s4)) #输出结果为 只执行一次 2 3 4 s2的id为: 278042421064 s3的id为: 278042421064 s4的id为: 278042421064
平时咱们在连接数据库时,一个程序,也是只须要一个连接就够了,咱们不但愿一个程序产生不少实例去链接到数据库,这样每一个连接都操做数据库,不但浪费了内存空间,还可能致使数据修改混乱api
class Sqlpool: __single = None #建立一个静态字段 def __init__(self): #封装数据库连接须要的信息 self.ip = "192.168.1.1" self.port = 3306 self.pwd = "1234567" self.username = "xxxxxx" #连接数据库 self.connect = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] #假如建立了9个连接数据库的线 @staticmethod def produce(): if Sqlpool.__single: #判断静态字段是否有值 return Sqlpool.__single #若是有值返回静态字段的值 else: Sqlpool.__single = Sqlpool() #没有就实例一个对象给他 return Sqlpool.__single #将实例返回 #这样,不管建立多少个访问,对象时,都是一个对象,这样不会占用内存 conn1 = Sqlpool.produce() #建立一个访问对象 conn2 = Sqlpool.produce() #建立二个访问对象
原理都差很少。这个没有装饰器好用服务器
class Singleton(object): def __init__(self): pass @classmethod def get(cls, *args, **kwargs): if not hasattr(Singleton, "_single"): Singleton._single = Singleton(*args, **kwargs) return Singleton._single
类方法这儿实现单列模式还有优化,就很少说了,是多线程问题。
这儿自己原理和静态方法差很少。多线程