___new__方法和__init__方法的区别
說明
1、繼承自object的新式類才有__new__
2、__new__至少要有一個參數(shù)cls,代表當(dāng)前類,此參數(shù)在實例化時由Python解釋器自動識別
3、__new__必須要有返回值,返回實例化出來的實例,這點在自己實現(xiàn)__new__時要特別注意,可以return父類(通過super(當(dāng)前類名, cls))__new__出來的實例,或者直接是object的__new__出來的實例
4、__init__有一個參數(shù)self,就是這個__new__返回的實例,__init__在__new__的基礎(chǔ)上可以完成一些其它初始化的動作,__init__不需要返回值
5、如果__new__創(chuàng)建的是當(dāng)前類的實例,會自動調(diào)用__init__函數(shù),通過return語句里面調(diào)用的__new__函數(shù)的第一個參數(shù)是cls來保證是當(dāng)前類實例,如果是其他類的類名,;那么實際創(chuàng)建返回的就是其他類的實例,其實就不會調(diào)用當(dāng)前類的__init__函數(shù),也不會調(diào)用其他類的__init__函數(shù)。
?
在繼承派生時的調(diào)用順序
1 class B(A): 2 def __init__(self,*args, **kwargs): 3 print "init B" 4 def __new__(cls,*args, **kwargs): 5 print "new B %s"%cls 6 #return super(B, cls).__new__(cls, *args, **kwargs) 7 return object.__new__(cls, *args, **kwargs)?
1、在定義子類時沒有重新定義__new__()時,Python默認是調(diào)用該類的直接父類的__new__()方法來構(gòu)造該類的實例,如果該類的父類也沒有重寫__new__(),那么將一直按此規(guī)矩追溯至object的__new__()方法,因為object是所有新式類的基類。
2、而如果子類中重寫了__new__()方法,那么你可以自由選擇任意一個的其他的新式類(必定要是新式類,只有新式類必定都有__new__(),因為所有新式類都是object的后代,而經(jīng)典類則沒有__new__()方法)的__new__()方法來制造實例,包括這個新式類的所有前代類和后代類,只要它們不會造成遞歸死循環(huán)。反正肯定不能調(diào)用自己的__new__,這肯定是死循環(huán)。
3、對于子類的__init__,其調(diào)用規(guī)則跟__new__是一致的,當(dāng)然如果子類和父類的__init__函數(shù)都想調(diào)用,可以在子類的__init__函數(shù)中加入對父類__init__函數(shù)的調(diào)用。
4、我們在使用時,盡量使用__init__函數(shù),不要去自定義__new__函數(shù),因為這兩者在繼承派生時的特性還是很不一樣的。
?
__new__ 的作用
1、__new__方法主要是當(dāng)你繼承一些不可變的class時(比如int, str, tuple), 提供給你一個自定義這些類的實例化過程的途徑。
假如我們需要一個永遠都是正數(shù)的整數(shù)類型,通過集成int,我們可能會寫出這樣的代碼。
但運行后會發(fā)現(xiàn),結(jié)果根本不是我們想的那樣,我們?nèi)稳坏玫搅?3。這是因為對于int這種 不可變的對象,我們只有重載它的__new__方法才能起到自定義的作用。
這是修改后的代碼:
通過重載__new__方法,我們實現(xiàn)了需要的功能。
2、實現(xiàn)單例
事實上,當(dāng)我們理解了__new__方法后,我們還可以利用它來做一些其他有趣的事情,比如實現(xiàn) 設(shè)計模式中的 單例模式(singleton) 。
因為類每一次實例化后產(chǎn)生的過程都是通過__new__來控制的,所以通過重載__new__方法,我們 可以很簡單的實現(xiàn)單例模式。
輸出結(jié)果:
value1 value1
True
可以看到obj1和obj2是同一個實例。
結(jié)果:
<type 'type'> <class '__main__.Singleton'> <type 'int'>
value1 value2
True
1 value1
?
3、實現(xiàn)自定義的metaclass。
?
?
參考鏈接:
http://www.cnblogs.com/ifantastic/p/3175735.html
https://my.oschina.net/leejun2005/blog/207371
?
轉(zhuǎn)載于:https://www.cnblogs.com/cmd61/p/11272834.html
總結(jié)
以上是生活随笔為你收集整理的___new__方法和__init__方法的区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IT知识架构和操作系统简介1
- 下一篇: 55. Jump Game