常见的在Python中实现单例模式的三种方法

单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

单例模式的要点有三个;一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。在Python中,单例模式有以下几种实现方式。

方法一、实现__new__方法,然后将类的一个实例绑定到类变量_instance上;如果cls._instance为None,则说明该类还没有被实例化过,new一个该类的实例,并返回;如果cls._instance不为None,直接返回_instance,代码如下:

class Singleton(object):

  def __new__(cls, *args, **kwargs):
    if not hasattr(cls, '_instance'):
      orig = super(Singleton, cls)
      cls._instance = orig.__new__(cls, *args, **kwargs)
    return cls._instance

class MyClass(Singleton):
  a = 1

one = MyClass()
two = MyClass()

#one和two完全相同,可以用id(), ==, is检测
print id(one)  # 29097904
print id(two)  # 29097904
print one == two  # True
print one is two  # True

方法二、本质上是方法一的升级版,使用__metaclass__(元类)的高级python用法,具体代码如下:

class Singleton2(type):

  def __init__(cls, name, bases, dict):
    super(Singleton2, cls).__init__(name, bases, dict)
    cls._instance = None

  def __call__(cls, *args, **kwargs):
    if cls._instance is None:
      cls._instance = super(Singleton2, cls).__call__(*args, **kwargs)
    return cls._instance

class MyClass2(object):
  __metaclass__ = Singleton2
  a = 1

one = MyClass2()
two = MyClass2()

print id(one)  # 31495472
print id(two)  # 31495472
print one == two  # True
print one is two  # True

方法三、使用Python的装饰器(decorator)实现单例模式,这是一种更Pythonic的方法;单利类本身的代码不是单例的,通装饰器使其单例化,代码如下:

def singleton(cls, *args, **kwargs):
  instances = {}
  def _singleton():
    if cls not in instances:
      instances[cls] = cls(*args, **kwargs)
    return instances[cls]
  return _singleton

@singleton
class MyClass3(object):
  a = 1

one = MyClass3()
two = MyClass3()

print id(one)  # 29660784
print id(two)  # 29660784
print one == two  # True
print one is two  # True
(0)

相关推荐

  • 详解python单例模式与metaclass

    单例模式的实现方式 将类实例绑定到类变量上 class Singleton(object): _instance = None def __new__(cls, *args): if not isinstance(cls._instance, cls): cls._instance = super(Singleton, cls).__new__(cls, *args) return cls._instance 但是子类在继承后可以重写__new__以失去单例特性 class D(Singleto

  • Python单例模式实例详解

    本文实例讲述了Python单例模式.分享给大家供大家参考,具体如下: 单例模式:保证一个类仅有一个实例,并提供一个访问他的全局访问点. 实现某个类只有一个实例的途径: 1,让一个全局变量使得一个对象被访问,但是他不能防止外部实例化多个对象. 2,让类自身保存他的唯一实例,这个类可以保证没有其他实例可以被创建. 多线程时的单例模式:加锁-双重锁定 饿汉式单例类:在类被加载时就将自己实例化(静态初始化).其优点是躲避了多线程访问的安全性问题,缺点是提前占用系统资源. 懒汉式单例类:在第一次被引用时,

  • 5种Python单例模式的实现方式

    本文为大家分享了Python创建单例模式的5种常用方法,供大家参考,具体内容如下 所谓单例,是指一个类的实例从始至终只能被创建一次. 方法1: 如果想使得某个类从始至终最多只有一个实例,使用__new__方法会很简单.Python中类是通过__new__来创建实例的: class Singleton(object): def __new__(cls,*args,**kwargs): if not hasattr(cls,'_inst'): cls._inst=super(Singleton,cl

  • Python单例模式的两种实现方法

    Python单例模式的两种实现方法 方法一  import threading class Singleton(object): __instance = None __lock = threading.Lock() # used to synchronize code def __init__(self): "disable the __init__ method" @staticmethod def getInstance(): if not Singleton.__instanc

  • Python设计模式之单例模式实例

    注:使用的是Python 2.7. 一个简单实现 复制代码 代码如下: class Foo(object):    __instance = None    def __init__(self):        pass    @classmethod    def getinstance(cls):        if(cls.__instance == None):            cls.__instance = Foo()        return cls.__instance

  • Python设计模式中单例模式的实现及在Tornado中的应用

    单例模式的实现方式 将类实例绑定到类变量上 class Singleton(object): _instance = None def __new__(cls, *args): if not isinstance(cls._instance, cls): cls._instance = super(Singleton, cls).__new__(cls, *args) return cls._instance 但是子类在继承后可以重写__new__以失去单例特性 class D(Singleto

  • Python单例模式实例分析

    本文实例讲述了Python单例模式的使用方法.分享给大家供大家参考.具体如下: 方法一 复制代码 代码如下: import threading    class Singleton(object):      __instance = None        __lock = threading.Lock()   # used to synchronize code        def __init__(self):          "disable the __init__ method&

  • 常见的在Python中实现单例模式的三种方法

    单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源.如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案. 单例模式的要点有三个:一是某个类只能有一个实例:二是它必须自行创建这个实例:三是它必须自行向整个系统提供这个实例.在Python中,单例模式有以下几种实现方式. 方法一.实现__new__方法,然后将类的一个实例绑定到类变量_instanc

  • python中实现栈的三种方法

    栈是一种线性数据结构,用先进后出或者是后进先出的方式存储数据,栈中数据的插入删除操作都是在栈顶端进行,常见栈的函数操作包括 empty() – 返回栈是否为空 – Time Complexity : O(1) size() – 返回栈的长度 – Time Complexity : O(1) top() – 查看栈顶元素 – Time Complexity : O(1) push(g) – 向栈顶添加元素 – Time Complexity : O(1) pop() – 删除栈顶元素 – Time

  • Python中表示字符串的三种方法

    Python中有三种方式表示字符串 第一种方法 使用单引号(') 用单引号括起来表示字符串,例如: str='this is string'; print str; 第二种方法 使用双引号(") 双引号中的字符串与单引号中的字符串用法完全相同, 例如: str="this is string"; print str; 第三种方法 使用三引号("') 利用三引号,表示多行的字符串,可以在三引号中自由的使用单引号和双引号, 例如: str="'this is

  • 在Python中调用ggplot的三种方法

    本文提供了三种不同的方式在Python(IPython Notebook)中调用ggplot. 在大数据时代,数据可视化是一个非常热门的话题.各个BI的厂商无不在数据可视化领域里投入大量的精力.Tableau凭借其强大的数据可视化的功能成为硅谷炙手可热的上市公司.Tableau的数据可视化的产品,其理论基础其实是<The Grammar of Graphic>,该书提出了对信息可视化的图表的语法抽象体系,数据的探索和分析可以由图像的语法来驱动,而非有固定的图表类型来驱动,使得数据的探索过程变得

  • 一文详解Python中实现单例模式的几种常见方式

    目录 Python 中实现单例模式的几种常见方式 元类(Metaclass): 装饰器(Decorator): 模块(Module): new 方法: Python 中实现单例模式的几种常见方式 元类(Metaclass): class SingletonType(type): """ 单例元类.用于将普通类转换为单例类. """ _instances = {} # 存储单例实例的字典 def __call__(cls, *args, **kwa

  • Python中实现单例模式的n种方式和原理

    在Python中如何实现单例模式?这可以说是一个经典的Python面试题了.这回我们讲讲实现Python中实现单例模式的n种方式,和它的原理. 什么是单例模式 维基百科 中说: 单例模式,也叫单子模式,是一种常用的软件设计模式.在应用这个模式时,单例对象的类必须保证只有一个实例存在.许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为.比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获

  • Python中修改字符串的四种方法

    在Python中,字符串是不可变类型,即无法直接修改字符串的某一位字符. 因此改变一个字符串的元素需要新建一个新的字符串. 常见的修改方法有以下4种. 方法1:将字符串转换成列表后修改值,然后用join组成新字符串 >>> s='abcdef' #原字符串 >>> s1=list(s) #将字符串转换为列表 >>> s1 ['a', 'b', 'c', 'd', 'e', 'f'] #列表的每一个元素为一个字符 >>> s1[4]='

  • Python中取整的几种方法小结

    前言 对每位程序员来说,在编程过程中数据处理是不可避免的,很多时候都需要根据需求把获取到的数据进行处理,取整则是最基本的数据处理.取整的方式则包括向下取整.四舍五入.向上取整等等.下面就来看看在Python中取整的几种方法吧. 1.向下取整 向下取整直接用内建的 int() 函数即可: >>> a = 3.75 >>> int(a) 3 2.四舍五入 对数字进行四舍五入用 round() 函数: >>> round(3.25); round(4.85)

  • Python中创建字典的几种方法总结(推荐)

    1.传统的文字表达式: >>> d={'name':'Allen','age':21,'gender':'male'} >>> d {'age': 21, 'name': 'Allen', 'gender': 'male'} 如果你可以事先拼出整个字典,这种方式是很方便的. 2.动态分配键值: >>> d={} >>> d['name']='Allen' >>> d['age']=21 >>> d[

  • python中取整数的几种方法

    目录 1.向下取整: int() 2.向上取整:ceil() 3.四舍五入:round() 4.分别取 1.向下取整: int() >>> a = 14.38 >>> int(a) 14 2.向上取整:ceil() 使用ceil()方法时需要导入math模块,例如 >>> import math >>> math.ceil(3.33) 4 >>> math.ceil(3.88) 4 3.四舍五入:round() &g

随机推荐