python中__new__函數(shù)的具體使用
__new__函數(shù)的介紹
new 是object基類提供的內(nèi)置靜態(tài)方法(雖然通常不需要顯式地使用 @staticmethod 裝飾器)。
__new__函數(shù)的作用
總結(jié):它的作用是為一個(gè)類創(chuàng)建并返回一個(gè)新的實(shí)例。
1、在內(nèi)存中分配對(duì)象的空間。
2、返回對(duì)象的引用。
__new__函數(shù)的重寫(xiě)
如果因?yàn)開(kāi)_new__函數(shù)重寫(xiě)導(dǎo)致沒(méi)有正確的返回實(shí)例化對(duì)象的引用,__init__函數(shù)將不被調(diào)用。
1、重寫(xiě)代碼示例:
注意點(diǎn):
1、重寫(xiě)時(shí)需要調(diào)用super,對(duì)父類做擴(kuò)展。
2、需要返回super的返回值,即實(shí)例的引用。(博主在這里認(rèn)為如果不返回實(shí)例的引用,會(huì)有內(nèi)存泄漏)
class MyClass:
def __new__(cls, *args, **kwargs):
print("__new__ is called. Creating instance.")
# 最關(guān)鍵的一步:調(diào)用父類的 __new__ 來(lái)創(chuàng)建實(shí)例
instance = super().__new__(cls)
# 這里可以對(duì) instance 做一些非常早期的操作
return instance # 必須返回實(shí)例!
def __init__(self, value):
print("__init__ is called. Initializing instance.")
self.value = value
# 測(cè)試
obj = MyClass(42)
print(obj.value)
輸出:
__new__ is called. Creating instance.
__init__ is called. Initializing instance.
42
2、錯(cuò)誤重寫(xiě)方法1:
重寫(xiě)__new__方法,直接覆蓋。無(wú)法成功的實(shí)例化對(duì)象。
class MyClass:
def __new__(cls, *args, **kwargs):
print("__new__ is called. Creating instance.")
def __init__(self, value):
print("__init__ is called. Initializing instance.")
self.value = value
# 測(cè)試
obj = MyClass(42)
print(obj)
輸出
__new__ is called. Creating instance.
None
3、錯(cuò)誤重寫(xiě)方法2:
調(diào)用了父類的__new__創(chuàng)建實(shí)例,但是未返回實(shí)例的引用。
class MyClass:
def __new__(cls, *args, **kwargs):
print("__new__ is called. Creating instance.")
# 最關(guān)鍵的一步:調(diào)用父類的 __new__ 來(lái)創(chuàng)建實(shí)例
super().__new__(cls)
def __init__(self, value):
print("__init__ is called. Initializing instance.")
self.value = value
# 測(cè)試
obj = MyClass(42)
print(obj)
輸出
__new__ is called. Creating instance.
None
4. __new__函數(shù) 的常見(jiàn)用途
用途 1:實(shí)現(xiàn)單例模式 (Singleton)
單例模式確保一個(gè)類只有一個(gè)實(shí)例。
class Singleton:
_instance = None # 類變量,用于保存唯一的實(shí)例
def __new__(cls, *args, **kwargs):
# 如果實(shí)例還不存在,就創(chuàng)建一個(gè)
if not cls._instance:
cls._instance = super().__new__(cls)
# 如果已經(jīng)存在,直接返回已有的實(shí)例
# 注意:每次調(diào)用 Singleton(),__init__ 仍然會(huì)被重新執(zhí)行
return cls._instance
def __init__(self, name):
self.name = name
# 測(cè)試
s1 = Singleton("First")
s2 = Singleton("Second")
print(s1 is s2) # 輸出: True,它們是同一個(gè)對(duì)象
print(s1.name) # 輸出: "Second" (注意!因?yàn)?__init__ 被第二次調(diào)用覆蓋了)
注意:上面的例子有一個(gè)“陷阱”,第二次創(chuàng)建實(shí)例時(shí),init 依然會(huì)執(zhí)行并修改了唯一實(shí)例的屬性。要避免這個(gè)問(wèn)題,需要更復(fù)雜的控制。
用途 2:繼承不可變類型 (如 int, str, tuple)
不可變類型在 init 里無(wú)法被修改,因?yàn)閷?duì)象在 init 被調(diào)用前就已經(jīng)創(chuàng)建好了。所以必須在 new 階段就修改它們。
class PositiveInteger(int):
def __new__(cls, value):
# 在創(chuàng)建對(duì)象之前,先對(duì)值進(jìn)行加工
return super().__new__(cls, abs(value))
# 測(cè)試
num = PositiveInteger(-5)
print(num) # 輸出: 5 (是一個(gè)真正的 int 類型)
print(type(num)) # 輸出: <class '__main__.PositiveInteger'>
用途 3:返回其他類的實(shí)例(工廠模式)
new 可以決定返回什么對(duì)象,不一定是當(dāng)前類的實(shí)例。
class ClassA:
pass
class ClassB:
pass
class MyFactory:
def __new__(cls, obj_type):
if obj_type == 'A':
return ClassA()
elif obj_type == 'B':
return ClassB()
else:
return None
# 測(cè)試
obj1 = MyFactory('A')
obj2 = MyFactory('B')
print(type(obj1)) # 輸出: <class '__main__.ClassA'>
print(type(obj2)) # 輸出: <class '__main__.ClassB'>
new與init的區(qū)別
| 特性 | new | init |
|---|---|---|
| 作用 | 創(chuàng)建對(duì)象,并返回這個(gè)新對(duì)象 | 初始化已被創(chuàng)建的對(duì)象 |
| 調(diào)用順序 | 先調(diào)用 | 后調(diào)用 |
| 參數(shù) | 第一個(gè)參數(shù)是 cls (類本身) | 第一個(gè)參數(shù)是 self (實(shí)例本身) |
| 返回值 | 必須返回創(chuàng)建的對(duì)象實(shí)例(通常是 cls 的實(shí)例) | 不應(yīng)該返回任何值(返回 None) |
| 本質(zhì) | 它是一個(gè)靜態(tài)方法 | 它是一個(gè)實(shí)例方法 |
到此這篇關(guān)于python實(shí)現(xiàn)__new__函數(shù)的文章就介紹到這了,更多相關(guān)python __new__函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Python中的?__init__、__new__?和?__call__示例詳解
- Python中的魔術(shù)方法__new__詳解
- Python中__new__()方法適應(yīng)及注意事項(xiàng)詳解
- python中__new__和__init__的實(shí)現(xiàn)
- python __init__與 __new__的區(qū)別
- Python中class內(nèi)置方法__init__與__new__作用與區(qū)別解析
- 詳解Python中__new__方法的作用
- Python 中類的構(gòu)造方法 __New__的妙用
- Python中__new__和__init__的區(qū)別與聯(lián)系
- Python 用__new__方法實(shí)現(xiàn)單例的操作
相關(guān)文章
Python實(shí)現(xiàn)識(shí)別花卉種類的示例代碼
“無(wú)窮小亮的科普日?!苯?jīng)常會(huì)發(fā)布一些鑒定網(wǎng)絡(luò)熱門生物視頻,既科普了生物知識(shí),又滿足觀眾們的獵奇心理。今天我們也來(lái)用Python鑒定一下網(wǎng)絡(luò)熱門植物2022-04-04
python機(jī)器人行走步數(shù)問(wèn)題的解決
這篇文章主要為大家詳細(xì)介紹了python機(jī)器人行走步數(shù)問(wèn)題的解決,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
python爬蟲(chóng)遇到403錯(cuò)誤的問(wèn)題及解決
這篇文章主要介紹了python爬蟲(chóng)遇到403錯(cuò)誤的問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-02-02
Python中flatten( ),matrix.A用法說(shuō)明
這篇文章主要介紹了Python中flatten( ),matrix.A用法說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07
Python自動(dòng)生成代碼 使用tkinter圖形化操作并生成代碼框架
這篇文章主要為大家詳細(xì)介紹了Python自動(dòng)生成代碼,使用tkinter圖形化操作并生成代碼框架,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09
Python中使用__hash__和__eq__方法的問(wèn)題
這篇文章主要介紹了Python中使用__hash__和__eq__方法的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09
使用PyQt5實(shí)現(xiàn)圖片查看器的示例代碼
這篇文章主要介紹了使用PyQt5實(shí)現(xiàn)圖片查看器的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04

