面向对象--实现单例模式

1.定义

一个类只能创建一个对象
为什么使用单例模式:
对于系统中的某些类来说,只有一个实例重要,比如:Windows中只能打开一个任务管理器。如果不使用单例模式,将会弹出多个任务管理器窗口,若显示的内容完全一致,则显示对象重复,浪费内存资源;若显示的内容不一致,则表示在这一瞬间系统有多个状态,与实际不符,也会给用户带来误解。因此确保系统中某个对象的唯一性很重要。

2.实现单例模式的三种方式

(1)装饰器实现单例模式

#装饰器实现单例模式
from functools import wraps
def singleton(cls):
    instances={}   #key是类名,value是对象名
    @wraps(cls)
    def wrapper(*args,**kwargs):
        name=cls.__name__  #获取类的名字
        if instances.get(name):
            return instances.get(name)  #直接返回缓存中的对象
        else:
            obj=cls(*args,**kwargs)
            instances[name]=obj
            return obj
    return wrapper
@singleton
class Person(object):
    pass
if __name__ == '__main__':
    p1=Person()
    p2=Person()
    print(p1 is p2)   #== 判断值是否相等,is判断值和id是否都相等

结果

True

(2)__new__魔术方法实现单例模式

#__new__魔术方法实现单例模式
class Person(object):
    def __new__(cls, *args, **kwargs):
        print('判断当前类是否拥有instance属性?',hasattr(cls,'instance')) #自省机制hasattr(,,,)判断对象或类是否具有某种属性
        if not hasattr(cls,'instance'):
            cls.instance=super(Person,cls).__new__(cls)
        return cls.instance
    def __init__(self,name):
        self.name=name
p1=Person('张三')
p2=Person('李四')
print('单例模式是否成功?',p1 is p2)

结果

判断当前类是否拥有instance属性? False
判断当前类是否拥有instance属性? True
单例模式是否成功? True

(3)metaclass自定义元类实现

#metaclass自定义元类实现
class Singleton(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):
    pass
p1=Person()
p2=Person()
print(p1 is p2)

结果

True
发布了36 篇原创文章 · 获赞 0 · 访问量 282

猜你喜欢

转载自blog.csdn.net/ANingL/article/details/103940592