之前Django开发使用过集中单例模式,今天来整理下这些实现单例模式的方式。
法一:使用__new__魔法方法
1 2 3 4 5
| class SingleMode1: def __new__(cls, *args, **kwargs): if not hasattr(cls, '_instance'): cls._instance = super().__new__(cls, *args, **kwargs) return cls._instance
|
说明:使用__new__方法对实例进行增强!
测试及结果:
1 2 3
| m1 = SingleMode1() m2 = SingleMode1() print(hash(m1) == hash(m2))
|
法二:使用自定义装饰器实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
def single(cls): _instance = {}
def generate_obj(*args, **kwargs): if _instance.setdefault(cls,None): _instance[cls] = cls(*args, **kwargs) return _instance[cls]
return generate_obj
@single class SingleMode4: pass
|
测试及结果:
1 2 3
| m5 = SingleMode4() m6 = SingleMode4() print(hash(m5) == hash(m6))
|
说明:其核心思想是利用类属性(这里用了字典类型)来判断实例是否已被创建过一次!
法三:使用@classmethod类装饰器实现
1 2 3 4 5 6 7 8
| class SingleMode2: _instance = None
@classmethod def create_obj(cls, *args, **kwargs): if not getattr(cls, '_instance'): cls._instance = super().__new__(cls, *args, **kwargs) return cls._instance
|
说明:其核心思想是利用类属性来判断实例是否已被创建过一次!
测试及结果:
1 2 3
| m3 = SingleMode2.create_obj() m4 = SingleMode2.create_obj() print(hash(m3) == hash(m4))
|
法三:Python的模块导入
1 2 3 4 5 6
| from django.conf import settings
settings = LazySettings()
|
注:使用懒加载的方式将配置文件动态放入到内存中执行,同时在内存中只需创建一份实例,全局都会使用这一份实例,不会再去创建新的实例。
结论:
单例模式的存在,是为了应对在某项业务在大量请求的情况下,需要创建大量的实例而出现的,单例模式大大降低创建大量实例消耗的内存资源。
Python使用单例的核心思想就是在创建实例前,判断类中是否已经存在保存该实例的类属性!