美文网首页
刷题1——面试题2:实现Singleton模式

刷题1——面试题2:实现Singleton模式

作者: 咋家 | 来源:发表于2019-06-16 10:08 被阅读0次

    面试题2:实现Singleton模式

    题目:设计一个类,我们只能生成该类的一个实例。

    首先,我们需要知道什么是单例模式(Singleton Pattern),这是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。也就是说,在整个系统中,只允许某个类出现一个实例。

    在python中,可以用多种方法来实现单例模式:

    • 使用模块
    • 使用new
    • 使用装饰器(decorator)
    • 使用元类(metaclass)

    1、使用模块

    在python中模块就是天然的单例模式,因为模块在第一次导入时,会生成.pyc文件,当再次导入时,就会直接加载.pyc文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得单例对象。

    #mysingleton.py
    class Singleton():
        def foo(self):
            pass
       
    my_singleton =Singleton()
     
    from mysingleton import my_singleton
     
    my_singleton.foo()
    

    2、使用new

    先来了解下new,在定义一个类时,使用的最多的就是init,而newcall很少使用到,都知道init方法负责对象的初始化,要想初始化,得先有对象不是,new的作用就是实例化一个对象并返回该实例对象,然后才能被init调用进行初始化。

    换个角度说,new是用来创建一个实例对象的,因此我们可以通过修改new方法来使类只出现一个实例,代码如下:

    class Singleton():
        _instance ={}
       
        def __new__(cls, *args, **kwargs):
            if cls not in cls._instance:
                cls._instance[cls] =super(Singleton, cls).__new__(cls)
               
            return cls._instance
       
    class MyClass(Singleton):
       
        def __init__(self, val):
            self.val =val
                  
    if __name__ =='__main__':
        a =MyClass(1)
        b =MyClass(2)
        print(a is b)   #True
    

    3、使用装饰器

    我们知道,装饰器可以动态的修改一个类或函数的功能,因此也可以使用装饰器来装饰某个类,使其只能生成一个实例。

    注意一点,python装饰器被装饰后的函数其实已经是另一个函数(函数名等函数属性会发生改变),为了不影响,python的functools包中提供了一个叫wraps的decorator来消除这样的副作用。

    from functools import wraps
     
    def singleton(cls):
        instances ={}
        @wraps(cls)
        def getinstance(*args, **kw):
            if cls not in instances:
                instances[cls] =cls(*args, **kw)
            return instances[cls]
        return getinstance
     
    @singleton
    class Myclass():
        a =1
       
    a =Myclass()
    b =Myclass()
    print(a is b)  #True
    

    4、使用元类

    元类(参考:深刻理解python中的元类)是用于创建类对象的类,类对象创建实例对象时一定会调用call方法,因此在调用call时候保证始终只创建一个实例即可,type是python中的一个元类。

    class Singleton(type):
        def __call__(cls, *args, **kwargs):
            if not hasattr(cls, '_instance'):
                cls._instance =super(Singleton, cls).__call__(*args, **kwargs)
            return cls._instance
       
    class Foo(metaclass=Singleton):
        pass
       
    f1 =Foo()
    f2 =Foo()
    print(f1 is f2) #True
    

    更多精彩,关注“咋家”

    咋家.png

    相关文章

      网友评论

          本文标题:刷题1——面试题2:实现Singleton模式

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