概念
- 解决什么问题? 如果在指定情况下,需要使用的对象是同一个,就没有必要浪费内存空间创建不同的对象,可通过单例设计模式来节省内存空间
- 设计模式? 已经存在的可以解决特定问题的方案【模板】,常用的有单利设计模式,工厂设计模式,代理微图设计模式,装饰者设计模式
- 单例设计模式? 程序运行的过程中,确保某一个类只有一个实例【对象】,不管在哪个模块中获取该实例,获取到的都是同一个实例
- 单例模式的核心 一个类有且只有一个实例,并且这个实例需要应用在程序的各个位置
使用(模块,new,装饰器,类中使用)
- 使用模块:Python中的模块本身就是一个单例,模块工作的原理:当模块被第一次导入的时候,会生成一个.pyc文件,当第二次导入的时候,会直接加载.pyc文件,跟原来的py文件没有关系
- 使用new:为了保证一个类只有一个实例,使用___new__来控制实例的创建过程
class Singleton(object): #1.声明一个类属性:可以使用类名访问 instance = None #2.重写new,new函数是一个类函数 def __new__(cls,*args,**kwargs): if cls.instance == None: cls.instance = super(Singleton,cls).__new__(cls,*args,**kwargs) print("----") return cls.instance class MyClass(Singleton): pass #__new__类似于构造函数,是在创建对象的时候调用 one = MyClass() #只有在第一个次调用的时候创建对象 two = MyClass() print(id(one) == id(two)) #true
说明:如果instance为None,则创建对象,并给instance赋值;如果instance不为None,则直接将instance返回
- 装饰器:将装饰器应用于一个函数上,则外部函数需要传一个函数;将装饰器应用到一个类上,则需要传一个类,使用cls代表类
#成员方法 def singleton(cls): #cls = Test instance = {} def getSingleton(*args, **kwargs): #思路:如果cls在字典中,则直接将结果【对象,实例】返回,如果cls不存在,则cls作为key,实例作为value存储到字典中 if cls not in instance: instance[cls] = cls(*args, **kwargs) #{Test:Test()} return instance[cls] return getSingleton @singleton class Test(object): pass t1 = Test() t2 = Test() print(id(t1) == id(t2)) #True
- 使用在类中
class Foo(object): #1.声明一个变量【类属性】 instance = None #2.向外界提供一个公开的函数,可以使用类名访问,用于返回当前类的唯一的对象 #方法命名格式;defaultInstance,currentInstance,getInstance @classmethod def getInstance(cls): if cls.instance: return cls.instance else: cls.instance = cls() return cls.instance if not cls.instance: cls.instance = cls() return cls.instance f1 = Foo.getInstance() f2 = Foo.getInstance() print(id(f1) == id(f2)) #True