国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

python設計模式-單例模式

darkbug / 711人閱讀

摘要:實現(xiàn)實現(xiàn)單例模式有多種方案使用提供了非常易用的類,只要繼承它,就會成為單例。參考鏈接單例模式最后,感謝女朋友支持。

問題:現(xiàn)代化的巧克力工廠具備計算機控制的巧克力鍋爐。鍋爐做的事情就是把巧克力和牛奶融在一起,然后送到下一個階段,以制成巧克力棒。下邊是一個巧克力公司鍋爐控制器的代碼,仔細觀察一下,這段代碼有什么問題?

class ChocolateBoiler(object):

    def __init__(self):
        self.empty = True
        self.boiled = False

    def fill(self):
        # 向鍋爐填充巧克力和牛奶混合物
        # 在鍋爐內(nèi)填充原料時,鍋爐必須是空的。
        # 一旦填入原料,就要把empty 和 boiled 標志設置好
        if self.empty:
            self.empty = False
            self.boiled = False

    def drain(self):
        # 排出煮沸的巧克力和牛奶
        # 鍋爐排出時,必須是滿的且煮沸的。
        # 排出完畢empty 設置為 true
        if not self.empty and self.boiled:
            self.empty = True

    def boil(self):
        # 將顱內(nèi)物煮沸
        # 煮混合物時,鍋爐內(nèi)必須是滿的且沒有煮沸過
        # 一旦煮沸,就把 boiled 設置為 true
        if not self.empty and not self.boiled:
            self.boiled = True

從代碼可以看出,他們加入了多種判斷,以防止不好的事情發(fā)生。如果同時存在兩個ChocolateBoiler實例,那這么多判斷豈不是失去作用了。那我們改如何實現(xiàn)這個需求呢?這個問題的核心是,我們要先判斷實例是不是已經(jīng)存在,如果存在就不再創(chuàng)建。

_chocolate_boiler_instance = None  # 聲明實例

def chocolate_boiler():
    global _chocolate_boiler_instance  # 使用全局變量

    if _chocolate_boiler_instance is not None: # 判斷是否存在,如果存在,直接返回
        return _chocolate_boiler_instance
    else:
        # 如果不存在,創(chuàng)建一個新的
        _chocolate_boiler_instance = ChocolateBoiler()
        return _chocolate_boiler_instance

現(xiàn)在我們需要獲取 ChocolateBoiler 實例的時候只需要調(diào)用 chocolate_boiler 方法獲取實例即可保證同時只有一個 ChocolateBoiler實例。

這種保證 ChocolateBoiler類只有一個實例,并提供一個全局訪問點的模式,就是單例模式

單例模式 定義

單例模式:確保一個類只有一個實例,并提供一個全局訪問點。

也就是說,我們使用單例模式要把某個類設計成自己管理的一個多帶帶實例,同時也避免其他類再自行產(chǎn)生實例。并且只允許通過單例類獲取單例的實例。

我們也提供對這個實例的全局訪問點:當你需要實例時,像類查詢,它會返回單個實例。

實現(xiàn)

python 實現(xiàn)單例模式有多種方案:

使用 metaclass

《python cookbook》提供了非常易用的 Singleton 類,只要繼承它,就會成為單例。

# python 3 代碼實現(xiàn)
class Singleton(type):

    def __init__(self, *args, **kwargs):
        self.__instance = None
        super().__init__(*args, **kwargs)

    def __call__(self, *args, **kwargs):
        if self.__instance is None:
            # 如果 __instance 不存在,創(chuàng)建新的實例
            self.__instance = super().__call__(*args, **kwargs)
            return self.__instance
        else:
            # 如果存在,直接返回
            return self.__instance


class Spam(metaclass=Singleton):

    def __init__(self):
        print("Creating Spam")

a = Spam()
b = Spam()

print(a is b)  # 這里輸出為 True

元類(metaclass)可以控制類的創(chuàng)建過程,它主要做三件事:

攔截類的創(chuàng)建

修改類的定義

返回修改后的類

例子中我們構造了一個Singleton元類,并使用__call__方法使其能夠模擬函數(shù)的行為。構造類 Spam 時,將其元類設為Singleton,那么創(chuàng)建類對象 Spam 時,行為發(fā)生如下:

Spam = Singleton(name,bases,class_dict),Spam 其實為Singleton類的一個實例。

創(chuàng)建 Spam 的實例時,Spam()=Singleton(name,bases,class_dict)()=Singleton(name,bases,class_dict).__call__(),這樣就將 Spam 的所有實例都指向了 Spam 的屬性 __instance上。

使用 new

我們可以使用 new 來控制實例的創(chuàng)建過程,代碼如下:

class Singleton(object):

    __instance = None

    def __new__(cls, *args, **kw):
        if not cls.__instance:
            cls.__instance = super().__new__(cls, *args, **kw)
        return cls.__instance

class Foo(Singleton):
    a = 1

one = Foo()
two = Foo()
assert one == two
assert one is two
assert id(one) == id(two)

通過 new 方法,將類的實例在創(chuàng)建的時候綁定到類屬性 __instance 上。如果cls.__instance 為None,說明類還未實例化,實例化并將實例綁定到cls.__instance 以后每次實例化的時候都返回第一次實例化創(chuàng)建的實例。注意從Singleton派生子類的時候,不要重載__new__。

使用裝飾器
import functools

def singleton(cls):
    """ Use class as singleton. """
    # 首先將 __new__ 方法賦值給 __new_original__
    cls.__new_original__ = cls.__new__

    @functools.wraps(cls.__new__)
    def singleton_new(cls, *args, **kw):
        # 嘗試從 __dict__ 取 __it__
        it =  cls.__dict__.get("__it__")
        if it is not None: # 如果有值,說明實例已經(jīng)創(chuàng)建,返回實例
            return it
        # 如果實例不存在,使用 __new_original__ 創(chuàng)建實例,并將實例賦值給 __it__
        cls.__it__ = it = cls.__new_original__(cls, *args, **kw)
        it.__init_original__(*args, **kw)
        return it
    # class 將原有__new__ 方法用 singleton_new 替換
    cls.__new__ = singleton_new
    cls.__init_original__ = cls.__init__
    cls.__init__ = object.__init__

    return cls

#
# 使用示例
#
@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

這種方法的內(nèi)部實現(xiàn)和使用 __new__ 類似:

首先,將 new 方法賦值給 new_original__,原有 new 方法用 singleton_new 替換,定義 init_original 并將 cls.__init 賦值給 init_original

在 singleton_new 方法內(nèi)部,嘗試從 dict 取 __it__(實例)

如果實例不存在,使用 new_original 創(chuàng)建實例,并將實例賦值給 __it__,然后返回實例

最簡單的方式

將名字singleton綁定到實例上,singleton就是它自己類的唯一對象了。

class singleton(object):
    pass
singleton = singleton()

https://github.com/gusibi/Metis/blob/master/apis/v1/schemas.py#L107 使用的就是這種方式,用來獲取全局的 request

Python 的模塊就是天然的單例模式,因為模塊在第一次導入時,會生成 .pyc 文件,當?shù)诙螌霑r,就會直接加載 .pyc 文件,而不會再次執(zhí)行模塊代碼。因此,我們只需把相關的函數(shù)和數(shù)據(jù)定義在一個模塊中,就可以獲得一個單例對象了。

參考鏈接

Creating a singleton in Python

Python單例模式

Why is __init__() always called after __new__()?


最后,感謝女朋友支持。

歡迎關注(April_Louisa) 請我喝芬達

文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/44499.html

相關文章

  • Python單例模式(Singleton)的N種實現(xiàn)

    摘要:本篇文章總結了目前主流的實現(xiàn)單例模式的方法供讀者參考。使用實現(xiàn)單例模式同樣,我們在類的創(chuàng)建時進行干預,從而達到實現(xiàn)單例的目的。 很多初學者喜歡用 全局變量 ,因為這比函數(shù)的參數(shù)傳來傳去更容易讓人理解。確實在很多場景下用全局變量很方便。不過如果代碼規(guī)模增大,并且有多個文件的時候,全局變量就會變得比較混亂。你可能不知道在哪個文件中定義了相同類型甚至重名的全局變量,也不知道這個變量在程序的某...

    Maxiye 評論0 收藏0
  • Python實現(xiàn)設計模式——單例模式

    摘要:前言單例模式是設計模式中最簡單最容易理解的一種,維基百科的定義如下單例模式,也叫單子模式,是一種常用的軟件設計模式。 前言 單例模式是設計模式(Design Pattern)中最簡單、最容易理解的一種,維基百科[1]的定義如下: 單例模式,也叫單子模式,是一種常用的軟件設計模式。在應用這個模式時,單例對象的類 類 (計算機科學))必須保證只有一個實例存在。許多時候整個系統(tǒng)只需要擁有一...

    CollinPeng 評論0 收藏0
  • Python 中的單例模式

    摘要:在中,我們可以用多種方法來實現(xiàn)單例模式使用模塊使用使用裝飾器使用元類使用模塊其實,的模塊就是天然的單例模式,因為模塊在第一次導入時,會生成文件,當?shù)诙螌霑r,就會直接加載文件,而不會再次執(zhí)行模塊代碼。 單例模式 單例模式(Singleton Pattern)是一種常用的軟件設計模式,該模式的主要目的是確保某一個類只有一個實例存在。當你希望在整個系統(tǒng)中,某個類只能出現(xiàn)一個實例時,單例對...

    khlbat 評論0 收藏0
  • Python中的單例模式

    摘要:使用元類可以控制類的創(chuàng)建過程,它主要做三件事攔截類的創(chuàng)建修改類的定義返回修改后的類使用元類實現(xiàn)單例模式的代碼如下執(zhí)行結果 單例模式 單例模式(Singleton Pattern)是一種常用的軟件設計模式,該模式的主要目的是確保某一個類只有一個實例存在。當你希望在整個系統(tǒng)中,某個類只能出現(xiàn)一個實例時,單例對象就能派上用場。 比如,某個服務器程序的配置信息存放在一個文件中,客戶端通過一個 ...

    church 評論0 收藏0
  • Python設計模式

    摘要:簡單工廠模式工廠模式有一種非常形象的描述,建立對象的類就如一個工廠,而需要被建立的對象就是一個個產(chǎn)品在工廠中加工產(chǎn)品,使用產(chǎn)品的人,不用在乎產(chǎn)品是如何生產(chǎn)出來的。單例模式的單例模式,所謂單例模式就是一個類只能創(chuàng)建一個實例化。 簡單工廠模式 工廠模式有一種非常形象的描述,建立對象的類就如一個工廠,而需要被建立的對象就是一個個產(chǎn)品;在工廠中加工產(chǎn)品,使用產(chǎn)品的人,不用在乎產(chǎn)品是如何生產(chǎn)出來...

    khs1994 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<