Python3.8.1
单例模式就是确保一个类只有一个实例.当你希望整个系统中,某个类只有一个实例时,单例模式就派上了用场
class MyClass(object):
def foo(self):
return None
obj1 = MyClass()
obj2 = MyClass()
print(obj1 is obj2)
print(id(obj1))
print(id(obj2))
class MyClass(object):
def foo(self):
return None
obj = MyClass()
使用:
from singleton.mysingleton import obj
python的模块就是天然的单例模式,因为模块在第一次导入的时候,会生成.pyc文件,当第二次导入的时候,就会直接加载.pyc文件,而不是再次执行模块代码.如果我们把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了
def singleton(cls):
"""装饰器函数"""
class_instance = {} # 定义一个接受实例的类
def singleton_inner(*args, **kwargs):
if cls not in class_instance: # 判断该类是否被实例化过
class_instance[cls] = cls(*args, **kwargs) # 没有被实例化过 -> 实例化 -> 将实例化的对象添加到字典中
return class_instance[cls] # 返回实例化对象
return singleton_inner
@singleton
class MyClass(object):
def foo(self):
return None
obj1 = MyClass()
obj2 = MyClass()
print(obj1 is obj2)
print(id(obj1))
print(id(obj2))
在类前加个装饰器,在这里装饰器的目的只有一个,就是在类实例化前,先判断这个类有没有实例化过,如果没有,则实例化,如果实例化过,测返回之前的实例化对象
class MyClass(object):
def foo(self):
return None
@classmethod
def get_instance(cls, *args, **kwargs):
"""实例化函数"""
if not hasattr(cls, '_instance'):
cls._instance = cls(*args, **kwargs)
return cls._instance
obj1 = MyClass.get_instance()
obj2 = MyClass.get_instance()
print(obj1 is obj2)
print(id(obj1))
print(id(obj2))
obj3 = MyClass()
print(id(obj3))
以这种方式实现单实例,有两个弊端:
class MyClass(object):
def foo(self):
return None
def __new__(cls, *args, **kwargs):
if not hasattr(cls, '_instance'):
cls._instance = super().__new__(cls)
return cls._instance
obj1 = MyClass()
obj2 = MyClass()
print(obj1 is obj2)
print(id(obj1))
print(id(obj2))
一个对象的实例化过程是先执行类的__new__方法,如果我们没有写,默认会调用object的__new__方法,返回一个实例化对象,然后再调用__init__方法,对这个对象进行初始化,我们可以根据这个实现单例