摘要:最近在學(xué)習(xí)設(shè)計(jì)模式而開(kāi)發(fā)的語(yǔ)言中比較中意的就是了在這里總結(jié)下設(shè)計(jì)模式一般分為三大類構(gòu)造型結(jié)構(gòu)型行為型先從創(chuàng)建型設(shè)計(jì)模式開(kāi)始創(chuàng)建型設(shè)計(jì)模式包括單例模式抽象工廠模式工廠方法模式生成器模式惰性初始化模式對(duì)象池模式原型模式單例模式單例模式的定義是保
最近在學(xué)習(xí)設(shè)計(jì)模式,而開(kāi)發(fā)的語(yǔ)言中比較中意的就是python了,在這里總結(jié)下.
設(shè)計(jì)模式一般分為三大類:構(gòu)造型,結(jié)構(gòu)型,行為型
先從創(chuàng)建型設(shè)計(jì)模式開(kāi)始,創(chuàng)建型設(shè)計(jì)模式包括:單例模式,抽象工廠模式,工廠方法模式,生成器模式,惰性初始化模式,對(duì)象池模式,原型模式.
單例模式單例模式的定義是:保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)它的全局訪問(wèn)點(diǎn).
先來(lái)看看14年前(沒(méi)寫錯(cuò))的前輩介紹的單例模式例程
from __future__ import print_function class Borg: __shared_state = {} def __init__(self): self.__dict__ = self.__shared_state self.state = "Init" def __str__(self): return self.state class YourBorg(Borg): pass if __name__ == "__main__": rm1 = Borg() rm2 = Borg() rm1.state = "Idle" rm2.state = "Running" print("rm1:{0}".format(rm1)) print("rm2:{0}".format(rm2)) rm2.state = "Zombie" print("rm1:{0}".format(rm1)) print("rm2:{0}".format(rm2)) print("rm1 id:{0}".format(id(rm1))) print("rm2 id:{0}".format(id(rm2))) rm3 = YourBorg() print("rm1:{0}".format(rm1)) print("rm2:{0}".format(rm2)) print("rm3:{0}".format(rm3)) # Output # rm1:Running # rm2:Running # rm1:Zombie # rm2:Zombie # rm1 id:140609170593696 # rm2 id:140609170593624 # rm1:Init # rm2:Init # rm3:Init
簡(jiǎn)單解釋下,需要get的點(diǎn)是下面這段代碼
__shared_state = {} def __init__(self): self.__dict__ = self.__shared_state self.state = "Init"
self.__dict__是對(duì)象的字典表示.將對(duì)象的屬性設(shè)為全局靜態(tài)變量.
根據(jù)輸出結(jié)果,rm1和rm2儼然是一個(gè)實(shí)例.然而打印出來(lái)的rm1,rm2的變量id是不一致的,所以rm1,rm2并不是同一個(gè)實(shí)例.但是卻有同樣的狀態(tài)和行為.但從結(jié)果上來(lái)看,確實(shí)實(shí)現(xiàn)了單例模式的要求.(雖然有種走捷徑的感覺(jué))
下面看看另一個(gè)版本的,其實(shí)就是換個(gè)形式,原理還是建多個(gè)實(shí)例,表現(xiàn)一致.其他部分的代碼和上面的一致.
class Borg(object): __state = {} def __new__(cls, *p, **k): self = object.__new__(cls, *p, **k) self.__dict__ = cls.__state return self def __init__(self): self.state = "Init"
單例模式的創(chuàng)建有很多種方式.
這里有討論鏈接描述
升級(jí)版,通過(guò)__metaclass__實(shí)現(xiàn).這個(gè)版本中同一個(gè)id說(shuō)明是同一個(gè)對(duì)象.
class Singleton(type): def __init__(self, name, bases, dict): super(Singleton, self).__init__(name, bases, dict) self._instance = None def __call__(self, *args, **kw): if self._instance is None: self._instance = super(Singleton, self).__call__(*args, **kw) return self._instance class MyClass(object): __metaclass__ = Singleton one = MyClass() two = MyClass() two.a = 3 print one.a # 3 print id(one) # 139798461922256 print id(two) # 139798461922256 print one == two # True print one is two # True
還可以通過(guò)裝飾器來(lái)實(shí)現(xiàn).這是第一個(gè)方法的高級(jí)版本,更pythonic,更elegant的方法.
這個(gè)例子中,單例類本身不知道自己是單例的,應(yīng)為他本身(自己的代碼)就不是單例的.
def singleton(cls, *args, **kw): instances = {} def _singleton(): if cls not in instances: instances[cls] = cls(*args, **kw) return instances[cls] return _singleton @singleton class MyClass(object): a = 1 def __init__(self, x=0): self.x = x one = MyClass() two = MyClass() two.a = 3 print one.a # 3 print id(one) # 140630714076048 print id(two) # 140630714076048 print one == two # True print one is two # True one.x = 1 print one.x # 1 print two.x # 1
好東西留到最后,來(lái)個(gè)超級(jí)無(wú)敵版的
class Singleton: """ A non-thread-safe helper class to ease Implementing singletons. This should be used as a decorator -- not a metaclass -- to the class that should be singleton. The decorated class can define one `__init__` function that takes onelythe `self` argument. Other than that, there are no restrictions that apply to the decorated class. To get the singleton instances, use the `instances` method. Trying to use `__call__` will result in a `TypeError` being raised. Limitations: The decorated class cannot be inherited from. """ def __init__(self, decorated): self._decorated = decorated def instance(self): """ Return the singleton instance. Upon this first call, it creates a new instance of decorated class and calls its `__init__` method. On all subsequent calls, the already created instance is returned. """ try: return self._instance except AttributeError: self._instance = self._decorated() return self._instance def __call__(self): raise TypeError("Singletons must be accessed through `instance()`.") def __instancecheck(self, inst): return isinstance(inst, self._decorated) @Singleton class Foo: def __init__(self): print "Foo created" # f = Foo() # TypeError: Singletons must be accessed through `instance()`. f = Foo.instance() g = Foo.instance() # Foo created print f is g # True
關(guān)于python的單例模式,各家說(shuō)法不一.可以根據(jù)不同的需求,使用不同的方式,適合的才是最好的.
參考文字:
https://zh.wikipedia.org/wiki/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F_(%E8%AE%A1%E7%AE%97%E6%9C%BA)
http://ginstrom.com/scribbles/2007/10/08/design-patterns-python-style/
http://code.activestate.com/recipes/66531/
http://blog.csdn.net/ghostfromheaven/article/details/7671853
http://stackoverflow.com/questions/31875/is-there-a-simple-elegant-way-to-define-singletons-in-python/31887#31887
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/37691.html
摘要:當(dāng)然,除了讓我們顯得更加專業(yè)之外,在自己所學(xué)習(xí)或者工作的項(xiàng)目中,適當(dāng)合理的使用設(shè)計(jì)模式,能夠給項(xiàng)目帶來(lái)很大的好處。 簡(jiǎn)單說(shuō)兩句 本文首發(fā)公眾號(hào)【一名打字員】 對(duì)不住各位老鐵了,年前說(shuō)好要更幾波JAVA的東西,又偷懶了,沒(méi)辦法,在這里用小錘錘偷偷錘了自己幾下。由于工作原因,更新時(shí)間不定,各位老鐵有問(wèn)題可以私聊我哈。 對(duì)于初學(xué)者或者是正在向中高級(jí)的Java程序猿(打字員)來(lái)說(shuō),時(shí)刻梳理自己...
摘要:大多數(shù)待遇豐厚的開(kāi)發(fā)職位都要求開(kāi)發(fā)者精通多線程技術(shù)并且有豐富的程序開(kāi)發(fā)調(diào)試優(yōu)化經(jīng)驗(yàn),所以線程相關(guān)的問(wèn)題在面試中經(jīng)常會(huì)被提到。將對(duì)象編碼為字節(jié)流稱之為序列化,反之將字節(jié)流重建成對(duì)象稱之為反序列化。 JVM 內(nèi)存溢出實(shí)例 - 實(shí)戰(zhàn) JVM(二) 介紹 JVM 內(nèi)存溢出產(chǎn)生情況分析 Java - 注解詳解 詳細(xì)介紹 Java 注解的使用,有利于學(xué)習(xí)編譯時(shí)注解 Java 程序員快速上手 Kot...
摘要:天入門三門編程語(yǔ)言,有可能嘛,尤其是對(duì)沒(méi)有基礎(chǔ)的同學(xué)來(lái)說(shuō)對(duì)于想學(xué)好的編程的人來(lái)說(shuō),無(wú)論從哪一門語(yǔ)言開(kāi)始入手,語(yǔ)言的本身其實(shí)并不是我們最應(yīng)該的關(guān)心的,至少不是作為一個(gè)初學(xué)者首先關(guān)心的。 7天入門三門編程語(yǔ)言,有可能嘛,尤其是對(duì)沒(méi)有基礎(chǔ)的同學(xué)來(lái)說(shuō)?對(duì)于想學(xué)好的編程的人來(lái)說(shuō),無(wú)論從哪一門語(yǔ)言開(kāi)始入手,語(yǔ)言的本身其實(shí)并不是我們最應(yīng)該的關(guān)心的,至少不是作為一個(gè)初學(xué)者首先關(guān)心的。 網(wǎng)絡(luò)上,網(wǎng)友們爭(zhēng)...
摘要:天入門三門編程語(yǔ)言,有可能嘛,尤其是對(duì)沒(méi)有基礎(chǔ)的同學(xué)來(lái)說(shuō)對(duì)于想學(xué)好的編程的人來(lái)說(shuō),無(wú)論從哪一門語(yǔ)言開(kāi)始入手,語(yǔ)言的本身其實(shí)并不是我們最應(yīng)該的關(guān)心的,至少不是作為一個(gè)初學(xué)者首先關(guān)心的。 7天入門三門編程語(yǔ)言,有可能嘛,尤其是對(duì)沒(méi)有基礎(chǔ)的同學(xué)來(lái)說(shuō)?對(duì)于想學(xué)好的編程的人來(lái)說(shuō),無(wú)論從哪一門語(yǔ)言開(kāi)始入手,語(yǔ)言的本身其實(shí)并不是我們最應(yīng)該的關(guān)心的,至少不是作為一個(gè)初學(xué)者首先關(guān)心的。 網(wǎng)絡(luò)上,網(wǎng)友們爭(zhēng)...
閱讀 1420·2021-11-22 15:11
閱讀 2847·2019-08-30 14:16
閱讀 2766·2019-08-29 15:21
閱讀 2924·2019-08-29 15:11
閱讀 2463·2019-08-29 13:19
閱讀 2995·2019-08-29 12:25
閱讀 426·2019-08-29 12:21
閱讀 2840·2019-08-29 11:03