python创建单例模式Singleton 四种方式

1.定义: 

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

 2.应用场景:

比如, 网站的计数器,一般也是采用单例模式实现,否则难以同步。再比如:Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源。

单例模式应用场景:参考链接

3.python实现方式

在 Python 中,我们可以用多种方法来实现单例模式

  • 1.使用装饰器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
# 3

优点:相比多重继承来说,使用装饰器会更加直观,更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

实现:

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 My_Singleton(object):
    def foo(self):
        pass

my_singleton = My_Singleton()


将上面的代码保存在文件 mysingleton.py 中,然后这样使用:

from mysingleton import my_singleton

my_singleton.foo()

优点:方便,简单

缺点:...在python中实现单例模式到底有没有意义……module本身就是单例导入,大家都是overthink了吧

Written by

说点什么

欢迎讨论

avatar

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

  Subscribe  
提醒