您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關(guān)Python項目中單例怎么利用__new__方法實現(xiàn),文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。
介紹
init 方法通常用在初始化一個類實例時候,但其實它不是實例化一個類的時候第一個被調(diào)用 的方法。當(dāng)使用 Student(id, name) 這樣的表達式來實例化一個類時,最先被調(diào)用的方法 其實是 new 方法。
new方法接受的參數(shù)雖然也是和init一樣,但init是在類實例創(chuàng)建之后調(diào)用,而 new方法正是創(chuàng)建這個類實例的方法。
new為對象分配空間,是內(nèi)置的靜態(tài)方法,new在內(nèi)存中為對象分配了空間也返回了對象的引用,init獲得了這個引用才初始化這個實例。
示例
一個非常簡單的單例
class A: instance = None def __new__(cls, *args, **kwargs): if cls.instance is None: cls.instance = super().__new__(cls) return cls.instance
因為new方法是一個靜態(tài)方法(也就是在定義的時候就沒有cls參數(shù)),所以在這里要傳入一個cls參數(shù),而且這里的new你改造過了,所以要返回爸爸的new方法。
按造這個方法改造的單例怎么new都是同一個實例,但init仍然會被執(zhí)行多次,也就是創(chuàng)建了幾個對象就調(diào)用幾次初始化方法。所以還要對init再進行一些判斷。
class A: instance = None init_flag = False # 初始化標(biāo)記 def __new__(cls, *args, **kwargs): if cls.instance is None: cls.instance = super().__new__(cls) return cls.instance def __init__(self): if A.init_flag: return print('執(zhí)行了初始化方法') A.init_flag = True if __name__ == '__main__': a = A() b = A() print(a) print(b)
輸出結(jié)果:
執(zhí)行了初始化方法
<main.A object at 0x00000210E6F09320>
<main.A object at 0x00000210E6F09320>
總結(jié)
通過重載new方法,可以比較簡單地實現(xiàn)單例,Python還有很多有趣的內(nèi)置函數(shù),有空可以再研究研究。
補充知識:Python餓漢式和懶漢式單例模式的實現(xiàn)
看代碼吧~
# 餓漢式 class Singleton(object): # 重寫創(chuàng)建實例的__new__方法 def __new__(cls): # 如果類沒有實例屬性,進行實例化,否則返回實例 if not hasattr(cls, 'instance'): cls.instance = super(Singleton, cls).__new__(cls) return cls.instance
餓漢式在創(chuàng)建的時候就會生成實例
# 懶漢式 class Singleton(object): __instance = None def __init__(self): if not self.__instance: print('調(diào)用__init__, 實例未創(chuàng)建') else: print('調(diào)用__init__,實例已經(jīng)創(chuàng)建過了:', __instance) @classmethod def get_instance(cls): # 調(diào)用get_instance類方法的時候才會生成Singleton實例 if not cls.__instance: cls.__instance = Singleton() return cls.__instance
關(guān)于Python項目中單例怎么利用__new__方法實現(xiàn)就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。