zoukankan      html  css  js  c++  java
  • **python实现的单例模式

    设计模式中,最简单的一个就是 “单例模式”。

    所谓单例,是指一个类只有一个全局实例。

    单例模式的使用场景:

    1. Windows的Task Manager(任务管理器)就是很典型的单例模式(这个很熟悉吧),想想看,是不是呢,你能打开两个windows task manager吗? 不信你自己试试看哦~ 

    2. windows的Recycle Bin(回收站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。

    3. 网站的计数器,一般也是采用单例模式实现,否则难以同步。

    4. 应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。

    5. Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源。

    6. 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。数据库软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率上的损耗还是非常昂贵的,如果用单例模式来维护,就可以大大降低这种损耗。

    7. 多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制。

    8. 操作系统的文件系统,也是大的单例模式实现的具体例子,一个操作系统只能有一个文件系统。

    9. HttpApplication 也是单位例的典型应用。熟悉ASP.NET(IIS)的整个请求生命周期的人应该知道HttpApplication也是单例模式,所有的HttpModule都共享一个HttpApplication实例.

    总结以上,不难看出:

      单例模式应用的场景一般出现在以下条件下:

      (1)资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如上述中的日志文件,应用配置。

      (2)控制资源的情况下,方便资源之间的互相通信。如线程池等。

     代码1:

    class B:
        __instance = None
        def __init__(self,name):
            self.name = name
        @classmethod
        def get_instance(cls):
            if cls.__instance:
               return cls.__instance
            else:
                obj = cls('xiaoyao')
                cls.__instance = obj
                return obj
    obj1 = B.get_instance()
    print(obj1)
    obj2 = B.get_instance()
    print(obj2)
    

      这样,我们通过静态方法 get_instance 创建新的实例就可以保证都一样了。

     代码2:

    class Singleton():
    
        # 定义静态变量实例
        __instance = None
    
        def __new__(cls, *args, **kwargs):
            if not cls.__instance:
                cls.__instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
            return cls.__instance
    
    if __name__ == "__main__":
        instance1 = Singleton()
        instance2 = Singleton()
    
        print(id(instance1))
        print(id(instance2))
    

      注:

    __new__是一个类方法,会创建对象时调用。而__init__方法是在创建完对象后调用,对当前对象的实例做一些一些初始化,无返回值。

    如果重写了__new__而在__new__里面没有调用__init__或者没有返回实例,那么__init__将不起作用。

    本例即是重写了__new__方法,如果 __instance 没有被赋值为 对象,那么执行父类原始的__new__方法创建对象并调用__init__方法实例化对象,保存在类变量 __instance中,否则,即表示__instance 已经被赋值为 对象,直接返回即可。

    代码3:

    def singleton(cls, *args, **kw):
        instances = {}
    
        def getinstance():
            if cls not in instances:
                instances[cls] = cls(*args, **kw)
            return instances[cls]
        return getinstance
    
    @singleton
    class MyClass:
    
      def __init__(self):
          self.name = 'rr'
    
    myobj1 = MyClass()
    myobj2 = MyClass()
    
    print(id(myobj1))
    print(id(myobj2))
    

      装饰器写法,其实原理和第一个写法一样。

    代码4:

    # mysingleton.py
    class My_Singleton(object):
        def foo(self):
            pass
    
    my_singleton = My_Singleton()
    
    # to use (test.py)
    from mysingleton import my_singleton
    
    obj1 = my_singleton
    obj2 = my_singleton
    
    print(id(obj1), id(obj2))
    

      作为python的模块是天然的单例模式.

  • 相关阅读:
    JavaSE 基础 第51节 定义自己的异常
    JavaSE 基础 第50节 Java中的异常链
    JavaSE 基础 第49节 手动抛出异常
    JavaSE 基础 第48节 Java中的异常声明
    JavaSE 基础 第47节 获取异常信息
    JavaSE 基础 第46节 异常的分类
    JavaSE 基础 第45节Java异常快速入门
    JavaSE 基础 第44节 引用外部类的对象
    JavaSE 基础 第43节 静态内部类
    通用爬虫
  • 原文地址:https://www.cnblogs.com/wumingxiaoyao/p/6728498.html
Copyright © 2011-2022 走看看