国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

Python單例模式

2019-11-14 17:39:44
字體:
來源:轉載
供稿:網(wǎng)友

所謂單例,是指一個類的實例從始至終只能被創(chuàng)建一次。

方法1

如果想使得某個類從始至終最多只有一個實例,使用__new__方法會很簡單。Python中類是通過__new__來創(chuàng)建實例的:

class Singleton(object):    def __new__(cls,*args,**kwargs):        if not hasattr(cls,'_inst'):            cls._inst=super(Singleton,cls).__new__(cls,*args,**kwargs)        return cls._instif __name__=='__main__':    class A(Singleton):        def __init__(self,s):            self.s=s          a=A('apple')       b=A('banana')    PRint id(a),a.s    print id(b),b.s

結果:

29922256 banana29922256 banana

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

方法2:

有時候我們并不關心生成的實例是否具有同一id,而只關心其狀態(tài)和行為方式。我們可以允許許多個實例被創(chuàng)建,但所有的實例都共享狀態(tài)和行為方式:

class Borg(object):    _shared_state={}    def __new__(cls,*args,**kwargs):        obj=super(Borg,cls).__new__(cls,*args,**kwargs)        obj.__dict__=cls._shared_state        return obj

將所有實例的__dict__指向同一個字典,這樣實例就共享相同的方法和屬性。對任何實例的名字屬性的設置,無論是在__init__中修改還是直接修改,所有的實例都會受到影響。不過實例的id是不同的。要保證類實例能共享屬性,但不和子類共享,注意使用cls._shared_state,而不是Borg._shared_state。

因為實例是不同的id,所以每個實例都可以做字典的key:

if __name__=='__main__':    class Example(Borg):        pass    a=Example()    b=Example()    c=Example()    adict={}    j=0    for i in a,b,c:        adict[i]=j        j+=1    for i in a,b,c:        print adict[i]

結果:

012

如果這種行為不是你想要的,可以為Borg類添加__eq__和__hash__方法,使其更接近于單例模式的行為:

class Borg(object):    _shared_state={}    def __new__(cls,*args,**kwargs):        obj=super(Borg,cls).__new__(cls,*args,**kwargs)        obj.__dict__=cls._shared_state        return obj    def __hash__(self):        return 1    def __eq__(self,other):        try:            return self.__dict__ is other.__dict__        except:            return Falseif __name__=='__main__':    class Example(Borg):        pass    a=Example()    b=Example()    c=Example()    adict={}    j=0    for i in a,b,c:        adict[i]=j        j+=1    for i in a,b,c:        print adict[i]

結果:

222

所有的實例都能當一個key使用了。

 方法3

當你編寫一個類的時候,某種機制會使用類名字,基類元組,類字典來創(chuàng)建一個類對象。新型類中這種機制默認為type,而且這種機制是可編程的,稱為元類__metaclass__ 。

class Singleton(type):    def __init__(self,name,bases,class_dict):        super(Singleton,self).__init__(name,bases,class_dict)        self._instance=None    def __call__(self,*args,**kwargs):        if self._instance is None:            self._instance=super(Singleton,self).__call__(*args,**kwargs)        return self._instanceif __name__=='__main__':    class A(object):        __metaclass__=Singleton           a=A()    b=A()    print id(a),id(b)

結果:

34248016 34248016

id是相同的。

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

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

創(chuàng)建A的實例時,A()=Singleton(name,bases,class_dict)()=Singleton(name,bases,class_dict).__call__(),這樣就將A的所有實例都指向了A的屬性_instance上,這種方法與方法1其實是相同的。

 方法4

python中的模塊module在程序中只被加載一次,本身就是單例的。可以直接寫一個模塊,將你需要的方法和屬性,寫在模塊中當做函數(shù)和模塊作用域的全局變量即可,根本不需要寫類。

而且還有一些綜合模塊和類的優(yōu)點的方法:

class _singleton(object):    class ConstError(TypeError):        pass    def __setattr__(self,name,value):        if name in self.__dict__:            raise self.ConstError        self.__dict__[name]=value    def __delattr__(self,name):        if name in self.__dict__:            raise self.ConstError        raise NameErrorimport syssys.modules[__name__]=_singleton()

python并不會對sys.modules進行檢查以確保他們是模塊對象,我們利用這一點將模塊綁定向一個類對象,而且以后都會綁定向同一個對象了。

將代碼存放在single.py中:

>>> import single>>> single.a=1>>> single.a=2ConstError>>> del single.aConstError

方法5

最簡單的方法:

class singleton(object):    passsingleton=singleton()

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


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 荣昌县| 松溪县| 普格县| 盘山县| 宾川县| 彰化市| 塘沽区| 汝城县| 罗山县| 屏东市| 瑞丽市| 石泉县| 潼南县| 阿瓦提县| 凌源市| 廊坊市| 汕头市| 车险| 柘城县| 册亨县| 卓资县| 出国| 江都市| 襄垣县| 庄河市| 石渠县| 舞阳县| 江阴市| 洛扎县| 塔河县| 辽阳县| 眉山市| 潢川县| 麻城市| 中宁县| 宁武县| 牙克石市| 天等县| 阳谷县| 哈尔滨市| 蓬莱市|