iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Python设计模式中单例模式的实现及在Tornado中的应用
  • 307
分享到

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

模式PythonTornado 2022-06-04 19:06:23 307人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

单例模式的实现方式 将类实例绑定到类变量上 class Singleton(object): _instance = None def __new__(cls, *args): if

单例模式的实现方式
将类实例绑定到类变量上


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(Singleton):

  def __new__(cls, *args):
    return super(D, cls).__new__(cls, *args)

使用装饰器实现


def singleton(_cls):
  inst = {}

  def getinstance(*args, **kwargs):
    if _cls not in inst:
      inst[_cls] = _cls(*args, **kwargs)
    return inst[_cls]
  return getinstance

@singleton
class MyClass(object):
  pass

问题是这样装饰以后返回的不是类而是函数,当然你可以singleton里定义一个类来解决问题,但这样就显得很麻烦了

使用__metaclass__,这个方式最推荐


class Singleton(type):
  _inst = {}
  
  def __call__(cls, *args, **kwargs):
    if cls not in cls._inst:
      cls._inst[cls] = super(Singleton, cls).__call__(*args)
    return cls._inst[cls]


class MyClass(object):
  __metaclass__ = Singleton


Tornado中的单例模式运用
来看看tornado.ioLoop中的单例模式:


class IOLoop(object):

  @staticmethod
  def instance():
    """Returns a global `IOLoop` instance.

Most applications have a single, global `IOLoop` running on the
main thread. Use this method to get this instance from
another thread. To get the current thread's `IOLoop`, use `current()`.
"""
    if not hasattr(IOLoop, "_instance"):
      with IOLoop._instance_lock:
        if not hasattr(IOLoop, "_instance"):
          # New instance after double check
          IOLoop._instance = IOLoop()
    return IOLoop._instance

为什么这里要double check?来看个这里面简单的单例模式,先来看看代码:


class Singleton(object):

  @staticmathod
  def instance():
    if not hasattr(Singleton, '_instance'):
      Singleton._instance = Singleton()
    return Singleton._instance

python 里,可以在真正的构造函数__new__里做文章:


class Singleton(object):

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

这种情况看似还不错,但是不能保证在多线程的环境下仍然好用,看图:

查看图片

出现了多线程之后,这明显就是行不通的。

1.上使线程同步
上锁后的代码:


import threading

class Singleton(object):

  _instance_lock = threading.Lock()
  
  @staticmethod
  def instance():
    with Singleton._instance_lock:
      if not hasattr(Singleton, '_instance'):
        Singleton._instance = Singleton()
    return Singleton._instance

这里确实是解决了多线程的情况,但是我们只有实例化的时候需要上锁,其它时候Singleton._instance已经存在了,不需要锁了,但是这时候其它要获得Singleton实例的线程还是必须等待,锁的存在明显降低了效率,有性能损耗。

2.全局变量
在 Java/c++ 这些语言里还可以利用全局变量的方式解决上面那种加锁(同步)带来的问题:


class Singleton {

  private static Singleton instance = new Singleton();
  
  private Singleton() {}
  
  public static Singleton getInstance() {
    return instance;
  }
  
}

Python 里就是这样了:


class Singleton(object):

  @staticmethod
  def instance():
    return _g_singleton

_g_singleton = Singleton()

# def get_instance():
# return _g_singleton

但是如果这个类所占的资源较多的话,还没有用这个实例就已经存在了,是非常不划算的,Python 代码也略显丑陋……

所以出现了像tornado.IOLoop.instance()那样的double check的单例模式了。在多线程的情况下,既没有同步(加锁)带来的性能下降,也没有全局变量直接实例化带来的资源浪费。

3.装饰器

如果使用装饰器,那么将会是这样:


import functools

def singleton(cls):
  ''' Use class as singleton. '''

  cls.__new_original__ = cls.__new__

  @functools.wraps(cls.__new__)
  def singleton_new(cls, *args, **kw):
    it = cls.__dict__.get('__it__')
    if it is not None:
      return it

    cls.__it__ = it = cls.__new_original__(cls, *args, **kw)
    it.__init_original__(*args, **kw)
    return it

  cls.__new__ = singleton_new
  cls.__init_original__ = cls.__init__
  cls.__init__ = object.__init__

  return cls

#
# Sample use:
#

@singleton
class Foo:
  def __new__(cls):
    cls.x = 10
    return object.__new__(cls)

  def __init__(self):
    assert self.x == 10
    self.x = 15

assert Foo().x == 15
Foo().x = 20
assert Foo().x == 20


def singleton(cls):
  instance = cls()
  instance.__call__ = lambda: instance
  return instance

#
# Sample use
#

@singleton
class Highlander:
  x = 100
  # Of course you can have any attributes or methods you like.

Highlander() is Highlander() is Highlander #=> True
id(Highlander()) == id(Highlander) #=> True
Highlander().x == Highlander.x == 100 #=> True
Highlander.x = 50
Highlander().x == Highlander.x == 50 #=> True

--结束END--

本文标题: Python设计模式中单例模式的实现及在Tornado中的应用

本文链接: https://www.lsjlt.com/news/15225.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 设计模式中的单例模式与PHP中的应用
    引言:设计模式是在软件设计过程中,经验丰富的软件工程师总结出来的一些解决特定问题的经典模式。其中,单例模式是最常用的设计模式之一。单例模式确保一个类只有一个实例,并提供了一个全局访问点来访问这个实例。在PHP中,单例模式被广泛应用于各种场景...
    99+
    2023-10-21
    单例模式 设计模式 PHP应用
  • JavaScript中的设计模式 单例模式
    目录1、什么是设计模式2、设计模式五大设计原则(SOLID)3、为什么需要设计模式?4、单例模式前言: 设计模式在我们编程中是十分重要的! 设计模式(Design pattern)...
    99+
    2024-04-02
  • java设计模式中如何实现单例模式
    这篇文章将为大家详细讲解有关java设计模式中如何实现单例模式,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。下面是一个简单的小实例://简单懒汉式 public class ...
    99+
    2023-05-30
    java
  • 理解JavaScript设计模式中的单例模式
    单例模式(Singleton Pattern)是最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 单例模式涉及到一个单一的类,该类负责创建自己...
    99+
    2024-04-02
  • Java设计模式的单例模式如何实现
    这篇文章主要介绍了Java设计模式的单例模式如何实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java设计模式的单例模式如何实现文章都会有所收获,下面我们一起来看看吧。单例模式单例模式顾名思义就是单一的实例...
    99+
    2023-06-29
  • java设计模式中的单例模式简单介绍
    这篇文章主要介绍“java设计模式中的单例模式简单介绍”,在日常操作中,相信很多人在java设计模式中的单例模式简单介绍问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java设计模式中的单例模式简单介绍”的疑...
    99+
    2023-06-02
  • 设计模式在C++中的应用案例
    是的,设计模式在 c++++ 中有广泛应用。观察者模式是一种一对一关系,其中一个对象(主体)管理依赖对象(观察者)并通知它们状态变化。在这个示例中,天气数据(主体)通知显示屏(观察者)状...
    99+
    2024-05-14
    c++ 设计模式
  • Java设计模式的单例模式实例分析
    本文小编为大家详细介绍“Java设计模式的单例模式实例分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java设计模式的单例模式实例分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。什么是单例模式单例模式(S...
    99+
    2023-06-29
  • Java中常用的设计模式之单例模式详解
    目录注意优点缺点使用场景一、实现方式二、实现方式三、测试总结注意 1、单例类只能有一个实例。 2、单例类必须自己创建自己的唯一实例。 3、单例类必须给所有其他对象提供这一实例。 优点...
    99+
    2024-04-02
  • js设计模式中单例模式的简要说明
    目录一. 认识单例模式二. 单例模式的分类  三. 具体实现和思想学习 1. 简单实现单例模式2. 透明单例模式3. 代理实现单例模式4. js的单例模...
    99+
    2024-04-02
  • java设计模式之怎么实现单例模式
    这篇文章主要介绍了java设计模式之怎么实现单例模式的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇java设计模式之怎么实现单例模式文章都会有所收获,下面我们一起来看看吧。单元素的枚举类型经常成为实现 Sing...
    99+
    2023-07-04
  • 在Python中如何实现单例模式
    本篇内容主要讲解“在Python中如何实现单例模式”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“在Python中如何实现单例模式”吧!方法一:使用装饰器实现单例模式。from functools...
    99+
    2023-06-01
  • java 中设计模式(装饰设计模式)的实例详解
    java 中设计模式(装饰设计模式)的实例详解应用场景:在不对原有对象类进行修改的基础上,给一个或多个已有的类对象提供增强额外的功能. 我觉得可以从字面理解,装饰,装饰房子。房子可以看成原有的类。等于你把一个已经建好的房子按照自己的想法再装...
    99+
    2023-05-31
    java 装饰模式 ava
  • Java23种设计模式中的单例模式你了解吗
    目录1、定义2、适用场景3、常见写法4、如何防止单例被破坏1.多线程破坏单例以及解决方法2.反射破坏单例以及解决方法3.序列化破坏单例以及解决方法5、优缺点6、总结1、定义 单例模式...
    99+
    2024-04-02
  • C++设计模式之简单工厂模式的实现示例
    前言 在我们要使用一个对象时,就必须通过类来实例化对象,也就是需要new一个对象。在new的过程是非常复杂的,要经过读文件->解析文本->创建对象->给属性设值等过...
    99+
    2024-04-02
  • Java中策略设计模式的实现及应用场景
    目录介绍实现总结介绍 Java策略模式(Strategy Pattern)是一种行为设计模式,它允许再运行时动态选择算法的行为.策略模式通过将算法封装在可互换的策略对象中,使得客户端...
    99+
    2023-05-17
    Java策略设计模式 Java设计模式 Java策略模式
  • 如何实现单例设计模式
    这篇文章主要讲解了“如何实现单例设计模式”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何实现单例设计模式”吧! 单例模式单例模式(Singleton Pattern)是 Java...
    99+
    2023-06-15
  • Python中的单例模式
    单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。 比如,某个服务器程序的配置信息存放在...
    99+
    2023-01-31
    模式 Python
  • java设计模式-单例模式实现方法详解
    目录饿汉式静态变量静态代码块懒汉式线程不安全线程安全双重检查静态内部类总结单例模式,属于创建类型的一种常用的软件设计模式。通过单例模式的方法创建的类在当前进程中只有一个实例(根据需要...
    99+
    2024-04-02
  • Python中单例模式的实现方法
    单例 — 让 类 创建的对象,在系统中 只有唯一的一个实例; 1)、定义一个类属性,初始值是 None ,用于记录 单例对象的引用;2)、重写 new 方法;3)、如果 ...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作