最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

單例模式的實現(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 里,可以在真正的構造函數(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

相關文章

  • Scrapy框架使用的基本知識

    Scrapy框架使用的基本知識

    今天小編就為大家分享一篇關于Scrapy框架使用的基本知識,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-10-10
  • Python學習之列表和元組的使用詳解

    Python學習之列表和元組的使用詳解

    如果說在Python語言中找一個最優(yōu)秀的數(shù)據(jù)類型,那無疑是列表,如果要在推薦一個,那我選擇元組。本篇文章我們的重心會放在列表上,元組可以看成不能被修改的列表,感興趣的可以了解一下
    2022-10-10
  • python 畫條形圖(柱狀圖)實例

    python 畫條形圖(柱狀圖)實例

    這篇文章主要介紹了python 畫條形圖(柱狀圖)實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04
  • python中partial()基礎用法說明

    python中partial()基礎用法說明

    這篇文章主要給大家介紹了關于python中partial()基礎用法的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用python具有一定的參考學習價值,需要的朋友們下面來一起看看吧
    2018-12-12
  • python隊列queue模塊詳解

    python隊列queue模塊詳解

    這篇文章主要為大家詳細介紹了python隊列queue模塊的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • 如何在pycharm中配置pyqt5設計GUI操作教程

    如何在pycharm中配置pyqt5設計GUI操作教程

    這篇文章主要介紹了如何在pycharm中配置pyqt5設計GUI的操作教程,有需要的朋友可以借鑒參考下,希望大家可以多多交流,討論相關問題共同提升
    2021-08-08
  • Python捕捉和模擬鼠標事件的方法

    Python捕捉和模擬鼠標事件的方法

    這篇文章主要介紹了Python捕捉和模擬鼠標事件的方法,涉及PyHook和PyWin32模塊的使用技巧,需要的朋友可以參考下
    2015-06-06
  • django Layui界面點擊彈出對話框并請求邏輯生成分頁的動態(tài)表格實例

    django Layui界面點擊彈出對話框并請求邏輯生成分頁的動態(tài)表格實例

    這篇文章主要介紹了django Layui界面點擊彈出對話框并請求邏輯生成分頁的動態(tài)表格實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-05-05
  • 如何在django里上傳csv文件并進行入庫處理的方法

    如何在django里上傳csv文件并進行入庫處理的方法

    這篇文章主要介紹了如何在django里上傳csv文件并進行入庫處理的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • 利用Python的PyPDF2庫提取pdf中的文字

    利用Python的PyPDF2庫提取pdf中的文字

    PyPDF2是一個用于處理PDF文件的Python庫,它提供了許多用于讀取和操作PDF文件的功能,對于需要處理PDF文件的Python應用程序,PyPDF2是一個非常實用的工具庫,本文將給大家詳細介紹一下如何通過Python的PyPDF2庫提取pdf中的文字,需要的朋友可以參考下
    2023-05-05

最新評論

宁乡县| 鄂托克旗| 佛坪县| 若尔盖县| 定安县| 漳平市| 黄骅市| 濮阳县| 专栏| 咸丰县| 水城县| 西充县| 沧源| 盐池县| 东乡族自治县| 开平市| 旅游| 鄂托克前旗| 宜君县| 长海县| 时尚| 舞钢市| 洛阳市| 米泉市| 化州市| 南安市| 新余市| 上蔡县| 嘉祥县| 日照市| 龙里县| 沐川县| 安新县| 保靖县| 云南省| 安化县| 灌云县| 左权县| 铁岭县| 武邑县| 靖西县|