欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python設(shè)計模式中單例模式的實現(xiàn)及在Tornado中的應用

 更新時間:2016年03月02日 18:13:38   作者:Damnever  
這篇文章主要介紹了Python設(shè)計模式中單例模式的實現(xiàn)及在Tornado中的應用,講解了單例模式用于設(shè)計Tornado框架中的線程控制方面的相關(guān)問題,需要的朋友可以參考下

單例模式的實現(xiàn)方式
將類實例綁定到類變量上

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)

使用裝飾器實現(xiàn)

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

問題是這樣裝飾以后返回的不是類而是函數(shù),當然你可以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 里,可以在真正的構(gòu)造函數(shù)__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

這種情況看似還不錯,但是不能保證在多線程的環(huán)境下仍然好用,看圖:

201632180733229.png (683×463)

出現(xiàn)了多線程之后,這明顯就是行不通的。

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已經(jīng)存在了,不需要鎖了,但是這時候其它要獲得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

但是如果這個類所占的資源較多的話,還沒有用這個實例就已經(jīng)存在了,是非常不劃算的,Python 代碼也略顯丑陋……

所以出現(xiàn)了像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

相關(guān)文章

  • Python中使用subprocess庫創(chuàng)建附加進程

    Python中使用subprocess庫創(chuàng)建附加進程

    這篇文章主要介紹了subprocess庫:Python中創(chuàng)建附加進程的相關(guān)知識,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-05-05
  • 學習python的前途 python掙錢

    學習python的前途 python掙錢

    在本文里我們給大家整理了關(guān)于學習python的前途以及python掙錢的方法整理,有興趣的朋友們閱讀下。
    2019-02-02
  • Python模擬簡單電梯調(diào)度算法示例

    Python模擬簡單電梯調(diào)度算法示例

    這篇文章主要介紹了Python模擬簡單電梯調(diào)度算法,涉及Python線程、隊列、時間延遲等相關(guān)操作技巧,需要的朋友可以參考下
    2018-08-08
  • python flask解析json數(shù)據(jù)不完整的解決方法

    python flask解析json數(shù)據(jù)不完整的解決方法

    這篇文章主要介紹了python flask解析json數(shù)據(jù)不完整的解決方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-05-05
  • Python+PyQt5實現(xiàn)網(wǎng)口功能測試詳解

    Python+PyQt5實現(xiàn)網(wǎng)口功能測試詳解

    這篇文章主要為大家詳細介紹了Python+PyQt5實現(xiàn)網(wǎng)口功能測試的相關(guān)知識,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2024-02-02
  • PyTorch實現(xiàn)FedProx聯(lián)邦學習算法

    PyTorch實現(xiàn)FedProx聯(lián)邦學習算法

    這篇文章主要為大家介紹了PyTorch實現(xiàn)FedProx的聯(lián)邦學習算法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • python實現(xiàn)代理服務功能實例

    python實現(xiàn)代理服務功能實例

    本文分析了代理服務的原理,并使用PYTHON實現(xiàn)了一個簡單的代理服務功能供大家參考使用
    2013-11-11
  • 淺談Python中的閉包

    淺談Python中的閉包

    簡單說,閉包就是根據(jù)不同的配置信息得到不同的結(jié)果。再來看看專業(yè)的解釋:閉包(Closure)是詞法閉包(Lexical Closure)的簡稱,是引用了自由變量的函數(shù)。這個被引用的自由變量將和這個函數(shù)一同存在,即使已經(jīng)離開了創(chuàng)造它的環(huán)境也不例外。
    2015-07-07
  • python神經(jīng)網(wǎng)絡Keras搭建RFBnet目標檢測平臺

    python神經(jīng)網(wǎng)絡Keras搭建RFBnet目標檢測平臺

    這篇文章主要為大家介紹了python神經(jīng)網(wǎng)絡Keras搭建RFBnet目標檢測平臺,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • python 基于selectors庫實現(xiàn)文件上傳與下載

    python 基于selectors庫實現(xiàn)文件上傳與下載

    這篇文章主要介紹了python 基于selectors庫實現(xiàn)文件上傳與下載的示例代碼,幫助大家更好的理解和使用python,感興趣的朋友可以了解下
    2020-12-12

最新評論