设计模式是经过总结、优化的,对我们经常会碰到的一些编程问题的可重用解决方案。后续会就常用的设计模式进行整理。
单例
顾名思义就是一个类至多只能实例化一次,也可以不实例化。
作用
保证一个类只有一个实例,并提供一个它的全局访问点。相当于全局变量,但防止了命名空间被污染。
使用场景
当类只需要有一个实例,比如说一个程序访问一个数据库,访问这个数据库的类只需要一个实例即可,防止随意的修改。python中的模块就是天然的单例模式,导入多次和导入一次是一样的;任务管理器也是单例模式。
实现:
代码示例1:使用__new__方法实现
class Singleton():
def __new__(cls,*args,**kw):
if not hasattr(cls,'_instance'):
print(cls)
obj = super(Singleton,cls) ## 表示获取Singleton父类对象
cls._instance = obj.__new__(cls,*args,**kw)
return cls._instance #返回实例化后的对象
class MyClass(Singleton):
a = 1
c1 = MyClass()
c2 = MyClass()
print(id(c1))
print(id(c2))
print(c1 == c2)
print(c1 is c2)
原理:
如果cls._instance为None说明该类还没有实例化过,实例化该类,并返回
如果cls._instance不为None,直接返回cls._instance
代码示例2:通过装饰器方法’实现
def singleton(cls, *args, **kw):
instances ={}
def get_instance():
if cls not in instances:
print(cls)
instances[cls] = cls( *args, **kw)
return instances[cls]
return get_instance
@singleton
class MyClass():
a = 1
c1 = MyClass()
c2 = MyClass()
print(id(c1))
print(id(c2))
print(c1 == c2)
print(c1 is c2)
原理:
如果cls的实例在instances字典中,就将其返回;否则将cls( *args, **kw)执行后返回的实例对象作为key放在instances字典中。
代码示例3:通过类实现
class Singleton():
def __init__(self):
pass
@classmethod
def getInstance(cls,*args,**kw):#类方法
print(cls)
if not hasattr(cls,'_instance'):
Singleton._instance = cls(*args,**kw)
return Singleton._instance
return Singleton._instance
s1 = Singleton.getInstance()
s2 = Singleton.getInstance()
print(id(s1))
print(id(s2))
原理:
在类方法中,判断类属性_instance是否存在,不存在的话就将类实例化之后赋值给_instance,否则的话直接返回。
其它模式待续。。。