zoukankan      html  css  js  c++  java
  • Python—程序设计:单例模式

    单例模式

      单例模式(Singleton Pattern)属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建,并提供一种访问其唯一对象的方式。

    特点:

      1.单例类只能有一个实例

      2.单利类必须自己创建自己的唯一实例

      3.单例类必须给其他对象提供这一实例

    解决问题:

      一个全局使用的类,频繁的创建于销毁。

    使用场景:

      需要控制实例数目,节省系统资源的时候。

    创建方法:

      判断单例类当前是否存在实例,如果有则返回这个实例,没有就创建

    实际用法:

      1.创建一个对象需要消耗过多的资源,比如I/O与数据库连接等

      2.Web中的计数器,不用每次刷新都在数据库里加一次,先用单利缓存起来

      3.线程池的设计一般也才有单例模式,方便线程控制

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

    代码实现:

    1.使用模块

    # 1.使用模块:
    """Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,
    当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。
    因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。"""
    
    
    class Singleton(object):
    
        def foo(self):
            pass
    
    
    singleton = Singleton()
    
    # 将上面的代码保存在文件 mysingleton.py 中,要使用时,直接在其他文件中导入此文件中的对象,这个对象即是单例模式的对象
    # from mysingleton import singleton

    2.使用元类metaclass

    # 2.使用元类metaclass
    """
    1.类由type创建,创建类时,type的__init__方法自动执行,类实例化,执行type的 __call__方法
    2.对象由类创建,创建对象时,类的__init__方法自动执行,对象()执行类的 __call__ 方法
    """
    
    
    class Singleton(type):
        """
        在元类Singleton的__call__方法对类属性__instance进行判断,如果__instance为None,
        说明类还未进行实例化,那么调用元类的父类(元类是type的子类)type的__call__方法,
        同时赋值给 cls.__instance。如果 cls.__instance 不为None,
        说明类已经进行过实例化,直接返回之前存储在类属性cls.__instance 中的类实例,即实现单例模式。
        """
        def __init__(cls, *args, **kwargs):
            cls.__instance = None
            super().__init__(*args, **kwargs)
    
        def __call__(cls, *args, **kwargs):
            if not cls.__instance:
                cls.__instance = super().__call__(*args, **kwargs)
            return cls.__instance
    
    
    class Foo(metaclass=Singleton):
        pass
    
    
    foo1 = Foo()
    foo2 = Foo()
    print(foo1 is foo2)

    3.使用__new__方法

    # 3.使用__new__方法
    class Singleton(object):
        """当我们实例化一个对象时,是先执行了类的__new__方法(我们没写时,默认调用object.__new__),
        实例化对象,然后再执行类的__init__方法,对这个对象进行初始化,
        所有我们可以基于这个,实现单例模式"""
    
        def __new__(cls, *args, **kwargs):
            if not hasattr(cls, '_instance'):  # 关键在于每一次实例化,我们都返回这同一个_instance对象
                cls._instance = super().__new__(cls)
            return cls._instance
    
    
    class Foo(Singleton):
        def __init__(self):
            pass
    
    
    foo1 = Foo()
    foo2 = Foo()
    print(foo2 is foo1)

    4.使用装饰器

    # 4.使用装饰器
    def singleton(cls):
        instance = {}
    
        def get_singleton(*args, **kwargs):
            if cls not in instance:                     # 判断是否存在字典中
                instance[cls] = cls(*args, **kwargs)    # 这里相当于Foo()
            return instance[cls]
    
        return get_singleton
    
    
    @singleton
    class Foo:
        pass
    
    
    foo1 = Foo()
    foo2 = Foo()
    print(foo1 is foo2)
  • 相关阅读:
    用javascript写星际飞机大战游戏
    Vue源码分析之实现一个简易版的Vue
    Vue源码分析之数据驱动
    Vue源码分析之虚拟DOM
    使用HbuilderX离线打包5+APP
    ERROR in build.js from UglifyJs
    PHP 的一些开发规范
    Markdown使用TOC自动生成导航栏
    Hexo博客skapp主题部署填坑指南
    Docker 官方安装详解
  • 原文地址:https://www.cnblogs.com/zivli/p/11442670.html
Copyright © 2011-2022 走看看