美文网首页
Python面试题之单例的四种实现方式

Python面试题之单例的四种实现方式

作者: 手艺人AA | 来源:发表于2019-05-05 00:13 被阅读0次

    如何在Python中实现单例模式,是面试编码环节时比较常见的题目了,这里我们介绍四种实现方式。

    • 1.使用装饰器
    • 2.使用基类
    • 3.使用元类
    • 4.使用模块导入
    原文来自微信公众号:技术90分,欢迎订阅,获取更多技术文章、资源分享
    

    定义

    单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中某个类只能出现一个实例时,单例对象就能派上用场。

    应用场景:

    1. 网站的计数器,程序内一般采用单例模式,否则难以同步
    2. Web应用的配置对象的读取:配置文件是共享资源
    3. 多线程的线程池:一般也是采用单例模式

    1.装饰器方式

    使用装饰器来实现单例模式也是python的经典面试题,可以一道简单的题目同时考察装饰器的理解和单例的实现。

    装饰器(decorator)可以动态地修改一个类或函数的功能。这里,我们也可以使用装饰器来装饰某个类,使其只能生成一个实例

    实现:

    
    def singleton(cls, *args, **kw):
        instances = {}
    
        def _singleton():
            if cls not in instances:
                instances[cls] = cls(*args, **kw)
            return instances[cls]
    
        return _singleton
    
    
    @singleton
    class MyClass4(object):
        a = 1
    
        def __init__(self, x=0):
            self.x = x
    
    
    one = MyClass4()
    two = MyClass4()
    
    two.a = 3
    print one.a
    
    • 优点:相比多重继承来说,使用装饰器会更加直观,更pythonic,更elegant的方法

    • 缺点:当你实例化Myclass的时候,得到的其实是singleton对象,是一个方法,而不是类,所以没办法使用类的本身的属性

    2.使用基类

    实现:

    
    class Singleton(object):
      _instance = None
      def __new__(class_, *args, **kwargs):
        if not isinstance(class_._instance, class_):
            class_._instance = object.__new__(class_, *args, **kwargs)
        return class_._instance
    
    class MyClass(Singleton, BaseClass):
      pass
      
    
    • 优点:一个真正的类

    • 缺点:多重继承,new可能会被重写。

    3.使用元类metaclass

    元类(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(BaseClass):
        __metaclass__ = Singleton
    
    #Python3
    class MyClass(BaseClass, metaclass=Singleton):
        pass
    
    • 优点:是一个真正的类,自动覆盖继承,合理使用了metaclass
    • 缺点:暂无

    4.直接使用模块

    其实Python的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,

    当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。

    因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。

    class MySingleton(object):
        def foo(self):
            pass
    
    mySingleton = MySingleton()
    
    
    将上面的代码保存在文件 mysingleton.py 中,然后这样使用:
    
    from mysingleton import mySingleton
    
    mySingleton.foo()
    
    
    • 优点:方便,简单
    • 缺点:有人说在python中实现单例模式到底有没有意义,module本身就是单例导入,在一些场景下考虑单例其实是没有必要的....

    相关文章

      网友评论

          本文标题:Python面试题之单例的四种实现方式

          本文链接:https://www.haomeiwen.com/subject/jqyqoqtx.html