關於__new__()的用法參考:python
http://www.myhack58.com/Article/68/2014/48183.htm安全
正文:框架
1、__new__()的用法:函數
__new__()是在新式類中新出現的方法,它做用在構造方法建造實例以前,能夠這麼理解,在Python 中 存在於類裏面的構造方法__init__()負責將類的實例化,而在__init__()啓動以前,__new__()決定是否 要使用該__init__()方法,由於__new__()能夠調用其餘類的構造方法或者直接返回別的對象來做爲本類 的實例。this
# encoding:utf-8 class A(object): def __new__(cls, x): print 'this is in A.__new__, and x is ', x return super(A, cls).__new__(cls) def __init__(self, y): print 'this is in A.__init__, and y is ', y class C(object): def __new__(cls, n): print 'this is in C.__new__, and n is ', n return super(C, cls).__new__(cls) def __init__(self, a): print 'this is in C.__init__, and a is ', a class B(A): def __new__(cls, z): print 'this is in B.__new__, and z is ', z return A.__new__(cls, z) def __init__(self, m): print 'this is in B.__init__, and m is ', m # class B(A): # def __new__(cls, z): # print 'this is in B.__new__, and z is ', z # return object.__new__(cls) # def __init__(self, m): # print 'this is ni B.__init__, and m is ', m if __name__ == '__main__': a = A(100) print '=' * 20 b = B(200) print type(b)
執行的結果爲:spa
this is in A.__new__, and x is 100 this is in A.__init__, and y is 100 ==================== this is in B.__new__, and z is 200 this is in A.__new__, and x is 200 this is in B.__init__, and m is 200 <class '__main__.B'>
說明:設計
1.定義A類做爲下面類的父類,A類繼承object類,由於須要重寫A類的__new__()函數,因此須要繼承object基類,成爲新式類,經典類沒有__new__()函數;code
2.子類在重寫__new__()函數時,寫return時必須返回有繼承關係的類的__new__()函數調用,即上面代碼中的B類繼承自A類,則重寫B類的__new__()函數,寫return時,只能返回A.__new__(cls)或者object.__new__(cls),不能返回C類的;htm
3.由註釋掉的代碼執行結果能夠看出,B類雖然繼承自A類,可是若是沒有重寫B類的__new__()函數,則默認繼承的還是object基類的__new__(),而不是A的;對象
4.B類的__new__()函數會在B類實例化時被調用,自動執行其中的代碼語句,可是重寫__new__()函數不會影響類的實例化結果,也就是說無論寫return時返回的是A的仍是object的,B類的實例化對象就是B類的,而不會成爲A類的實例化對象;只是在實例化時,若是返回的是A.__new__(cls),則會執行A類中定義的__new__()函數;
5.__new__()函數肯定了類的參數的個數,object類默認定義的__new__()函數的參數爲(cls, *more),但若是在子類中重寫了__new__(cls, x), 則實例化類時,須要傳入一個x參數,而__init__()函數接受到的有兩個參數,一個是實例化生成的實例對象self代替,一個是傳入的實參x的值;
>>> >>> class A(object): def __init__(self, x): self.x = x print '__init__ called.' def foo(self): print self.x >>> >>> a = A('123') __init__ called. >>> >>> a.foo() 123 >>>
在A('123')實例化類時,自動調用__init__()方法定義的self.x = x和print '__init__ called.',咱們能看到‘__init__ called.’被打印,看不到self.x = x的執行,可是在調用a.foo()時,能執行成功,就是拜self.x = x的功能所賜;由於若是沒有__init__()方法中的self.x = x,實例對象將沒法追溯到foo()函數中的self.x是從哪裏來的,從而會報錯;也就是在__init__()函數中將外部傳入的參數x賦值給self.x,從而是self.x在類A中暢行無阻;
三.__call__()的用法
__call__()方法可以讓類的實例對象,像函數同樣被調用;
>>> >>> class A(object): def __call__(self, x): print '__call__ called, print x: ', x >>> >>> a = A() >>> a('123') __call__ called, print x: 123 >>>
看a('123')這是函數的調用方法,這裏a其實是類對象A的實例對象,實例對象能想函數同樣傳參並被調用,就是__call__()方法的功能;
4、__del__()的用法
若是__new__()和__init__()函數時類的構造函數(即在類實例化時自動執行函數中定義的內容),那麼__del__()是類的析構函數,是python垃圾回收機制的實際應用,當類的全部引用都被刪除後,該類就會被系統從內存中刪除,注意是全部的引用都被刪除哦,而不是每一次刪除;
>>> class D(object): def __init__(self): print 'this is D.__init__()' def __del__(self): print 'this is D.__del__()' >>> >>> d = D() this is D.__init__() >>> >>> d2 = d >>> d3 = d >>> >>> del d >>> del d2 >>> del d3 this is D.__del__() >>>
將D()實例化對象賦值給d,後d2,d3都是指向D()的此次實例化對象,刪除d和d2的引用都不會觸發__del__()函數,最後一個d3的引用被刪除,就會觸發__del__(),此時D()的這一次實例化的對象就被清除;
最後:
用一段簡單的代碼,來整體感覺一下三個方法的用法和區別:
>>> >>> class A(object): def __init__(self, x): print 'x in __init__', x def __new__(cls, y): print 'y in __new__', y return super(A, cls).__new__(cls) def __call__(self, z): print 'z in __call__', z def __del__(self): print 'this is in A.__del__()' >>> >>> A('123')('abc') y in __new__ 123 x in __init__ 123 z in __call__ abc this is in A.__del__() >>>
由執行結果能夠看出,雖然__init__()方法定義在__new__()方法以前,可是結果中先展現了__new__()方法的執行結果;