单例模式
1、定义
一个类只能创建一个对象
为什么要使用单例模式:
对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务, 但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有 一个计时工具或ID(序号)生成器。如在Windows中就只能打开一个任务管理器。如果不使用机制 对窗口对象进行唯一化,将弹出多个窗口,如果这些窗口显示的内容完全一致,则是重复对象, 浪费内存资源;如果这些窗口显示的内容不一致,则意味着在某一瞬间系统有多个状态,与实际 不符,也会给用户带来误解,不知道哪一个才是真实的状态。因此有时确保系统中某个对象的唯 一性即一个类只能有一个实例非常重要
2、实现单例模式的三种方法
(1)装饰器实现单例模式
(2)__ new __魔术方法实现
(3)metaclass自定义元类实现
""" (1)装饰器实现单例模式 """
from functools import wraps
# 用装饰器来装饰类
def singleton(cls):
instances = {} # {Person : obj} key值是类名 , value值是对象名
@wraps(cls)
def wrapper(*args, **kwargs):
if instances.get(cls.__name__): #如果存在对象,返回存在的这个对象
return instances.get(cls.__name__)
else: # 如果不存在对象,创建对象cls(),并存起来
obj = cls( *args, **kwargs)
instances[cls.__name__] = obj
return obj
return wrapper
@singleton
class Person(object):
pass
if __name__ == '__main__':
p1 = Person()
p2 = Person()
print(p1,p2) # p1,p2地址相同
print("单例化成功:", p1 is p2)
运行结果:
(2)__ new __ 方法实现
"""__new__ 魔术方法实现单例模式"""
class Person(object):
_instance = None # 设置类属性,存储已经创建好的对象
def __init__(self):
print("执行构造方法")
def __new__(cls, *args, **kwargs):
print ("new方法在实例化对象之前执行,返回对象本身")
if cls._instance:
return cls._instance
else:
obj = object.__new__(cls) #调用父类的__new__方法创建对象
cls._instance = obj
return obj
if __name__ == '__main__':
p1 = Person()
p2 = Person()
print(p1,p2)
(3)metaclass自定义元类实现
"""metaclass 自定义元类实现单例模式"""
class Singleton(type):
"""自定义元类,父类是type"""
cache = {}
def __call__(cls):
if cls not in cls.cache: # 判断类是否以及实例化
cls.cache[cls] = super(Singleton, cls).__call__()
return cls.cache[cls]
class Person(object, metaclass=Singleton): # 指定类Person是由元类Singleton创建的
pass
p1 = Person()
p2 = Person()
print(p1, p2)
来源:CSDN
作者:小黑--
链接:https://blog.csdn.net/qq_41645466/article/details/103898547