zoukankan      html  css  js  c++  java
  • Python 中的单例模式

    1.什么是单例模式
     
    单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。单例模式能控制一个类只能产生一个对象。
     
    2.为什么需要单例模式
    • 当每个实例都会占用资源,而且实例初始化会影响性能,这个时候就可以考虑使用单例模式,它给我们带来的好处是只有一个实例占用资源,并且只需初始化一次;
    • 当有同步需要的时候,可以通过一个实例来进行同步控制,比如对某个共享文件(如日志文件)的控制,对计数器的同步控制等,这种情况下由于只有一个实例,所以不用担心同步问题。
     
    3.单例模式应用场景
    • Python的logger就是一个单例模式,用以日志记录
    • Windows的资源管理器是一个单例模式
    • 线程池,数据库连接池等资源池一般也用单例模式
    • 网站计数器
    4.在 Python 中,实现单例模式的四种方式
    • 使用模块
    • 使用装饰器(decorator)
    • 使用 __new__
    • 使用元类
    4.1 使用模块
        Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。
    如果我们真的想要一个单例类,可以考虑这样做:
    # mysingleton.py 
    class My_Singleton(object): 
        def foo(self): 
            pass 
    my_singleton = My_Singleton()

    将上面的代码保存在文件 mysingleton.py 中,然后这样使用:

    from mysingleton import my_singleton
    my_singleton.foo()
     
    4.2 使用装饰器
        装饰器维护一个字典对象instances,缓存了所有单例类,只要单例不存在则创建,已经存在直接返回该实例对象。
    我们定义一个装饰器 singleton,它返回了一个内部函数 wrapper,该函数会判断某个类是否在字典 instances 中,如果不存在,则会将 cls 作为 key,cls(*args, **kw) 作为 value 存到 instances 中,否则,直接返回 instances[cls]。
     
    使用装饰器实现单例模式的代码如下:
    def singleton(cls):
        instances = {}
    
        def wrapper(*args, **kwargs):
            if cls not in instances:
                instances[cls] = cls(*args, **kwargs)
            return instances[cls]
    
        return wrapper
    
    
    @singleton
    class Foo(object):
        pass
     
    4.3 使用__new__
     
    __new__方法:  __new__()方法用于定义创建对象时执行的操作
    object类中的__new__()方法完成对象创建过程中的内存空间申请,对象属性初始化等一系列的操作。__new__是真正创建实例对象时用到的方法,所以重写基类的__new__方法,以此来保证创建对象的时候只生成一个实例。
    注意事项:    
    1.__new__()方法创建对象时自动运行。     
    2.覆盖object类中的__new__方法后创建对象    将执行覆盖后的方法。
    注意事项:  
    __new__()方法仅仅是python开放出来给用户干预创建对象时的一个操作入口,该方法并不是直接完成分配内存、创建对象的操作,创建对象的操作由python底层统一管理。
     
    使用__new__方法实现单例模式的代码如下:
    class Singleton(object):
        _instance = None
    
        def __new__(cls, *args, **kw):
            if not cls._instance:
                cls._instance = super(Singleton, cls).__new__(cls, *args, **kw)
            return cls._instance
    
    class MyClass(Singleton):
        pass
    
    foo1 = MyClass()
    foo2 = MyClass()
    print(foo1)
    print(foo2)
     
    4.4 使用元类
    元类是用于创建类对象的类,类对象创建实例对象时一定会调用__call__方法,因此在调用__call__时候保证始终只创建一个实例即可,type是python中的一个元类。
    元类(metaclass)可以控制类的创建过程,它主要做三件事:
      拦截类的创建
      修改类的定义
      返回修改后的类
     
    使用元类实现单例模式的代码如下:
    class Singleton(type):
        _instances = {}
        def __call__(cls, *args, **kwargs):
            if cls not in cls._instances:
                cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
            return cls._instances[cls]
    
    # Python2
    # class MyClass(object):
    #     __metaclass__ = Singleton
    
    # Python3
    class MyClass(metaclass=Singleton):
        pass
    
    foo1 = MyClass()
    foo2 = MyClass()
    print(foo1)
    print(foo2)
  • 相关阅读:
    【.NET】VS2013创建Windows服务与调试服务
    【JS】处理数据四舍五入(tofixed与round的区别详解)
    【微信小程序】 基础语义笔记2:基本组件、获取节点信息
    面向对象和面向过程的优点和缺点
    【微信小程序】 基础语义笔记1:配置、页面文件、组件。
    【微信小程序】 wxParse组件
    zookeeper 碎片知识点
    zookeeper 基本概念
    RocketMQ 知识点
    单例模式---双层检验锁+volatile
  • 原文地址:https://www.cnblogs.com/new-rain/p/10023473.html
Copyright © 2011-2022 走看看