美文网首页
单例模式学习

单例模式学习

作者: vckah | 来源:发表于2018-07-03 11:02 被阅读0次

    单例模式保证系统中只有一个实例对象。比如说打开一个配置文件的实例,我们需要保证在系统运行过程中,这个配置文件不能同时被打开,所以构造这个文件的实例只能有一个。
    Python 中有几种方式可以实现单例模式

    • 使用 new
    • 使用模块
    • 使用装饰器
    • 使用元类
      先来看一看使用 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
    
    # 这样的话,在系统中实例化多个 MyClass 都可以保证只有一个 MyClass
    

    但是以上这个只在单线程中是单例,如果在多线程环境中,其并不是单例。为此我们需要额外的加上一把锁。

    from threading import threading
    class Singleton(object):
        _instance = None
    ->  lock = threading.RLock()
        def __new__(cls, *args, **kw):
    -->>    cls.lock.acquire()
            if not cls._instance:
                cls._instance = super(Singleton, cls).__new__(cls, *args, **kw)  
          -->>  cls.lock.release()
            return cls._instance  
    
    class MyClass(Singleton):  
        pass
    # 这里使用了 RLock。
    #为什么不使用 Lock 呢,是因为一个 Lock 可能会出现死锁。
    #RLock 保证可以获取到多个锁
    

    另外说一说模块。Python 加载模块时,只会在第一次遇见的时候导入,之后再次遇到导入这个模块时,Python 并不会再次导入,而是会去内存中查找这个模块,并将其信息放置到当前环境中。

    # test.py
    class My_Singleton(object):
        def test(self):
            pass
     
    my_singleton = My_Singleton()
    

    这里的 my_singleton 就是一个单例。在其他 py 文件中导入它

    from test import my_singleton
    
    my_singleton.test()
    
    • 装饰器
      与类的写法差不多
    def singleton(cls, *args, **kwargs):
        instance = {}
        def getinstance(cls, *args, **kw):
            if cls not in instance:
                instance[cls] = cls(*args, **kwargs)
            return instance[cls]
        return getinstance
    
    @singleton
    class MyClass(object):  
        pass
    

    元类的话,还不太了解,好像是用到了 metaclass ,以后再补充。

    相关文章

      网友评论

          本文标题:单例模式学习

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