单例模式
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