日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

___new__方法和__init__方法的区别

發布時間:2024/8/26 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ___new__方法和__init__方法的区别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1 class A(object): 2 def __init__(self,*args, **kwargs): 3 print "init A" 4 def __new__(cls,*args, **kwargs): 5 print "new A %s"%cls 6      #return super(A, cls).__new__(cls, *args, **kwargs) 7 return object.__new__(cls, *args, **kwargs)

說明

1、繼承自object的新式類才有__new__

2、__new__至少要有一個參數cls,代表當前類,此參數在實例化時由Python解釋器自動識別

3、__new__必須要有返回值,返回實例化出來的實例,這點在自己實現__new__時要特別注意,可以return父類(通過super(當前類名, cls))__new__出來的實例,或者直接是object的__new__出來的實例

4、__init__有一個參數self,就是這個__new__返回的實例,__init__在__new__的基礎上可以完成一些其它初始化的動作,__init__不需要返回值

5、如果__new__創建的是當前類的實例,會自動調用__init__函數,通過return語句里面調用的__new__函數的第一個參數是cls來保證是當前類實例,如果是其他類的類名,;那么實際創建返回的就是其他類的實例,其實就不會調用當前類的__init__函數,也不會調用其他類的__init__函數。

?

在繼承派生時的調用順序

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默認是調用該類的直接父類的__new__()方法來構造該類的實例,如果該類的父類也沒有重寫__new__(),那么將一直按此規矩追溯至object的__new__()方法,因為object是所有新式類的基類。

2、而如果子類中重寫了__new__()方法,那么你可以自由選擇任意一個的其他的新式類(必定要是新式類,只有新式類必定都有__new__(),因為所有新式類都是object的后代,而經典類則沒有__new__()方法)的__new__()方法來制造實例,包括這個新式類的所有前代類和后代類,只要它們不會造成遞歸死循環。反正肯定不能調用自己的__new__,這肯定是死循環。

3、對于子類的__init__,其調用規則跟__new__是一致的,當然如果子類和父類的__init__函數都想調用,可以在子類的__init__函數中加入對父類__init__函數的調用。

4、我們在使用時,盡量使用__init__函數,不要去自定義__new__函數,因為這兩者在繼承派生時的特性還是很不一樣的。

?

__new__ 的作用

1、__new__方法主要是當你繼承一些不可變的class時(比如int, str, tuple), 提供給你一個自定義這些類的實例化過程的途徑。

假如我們需要一個永遠都是正數的整數類型,通過集成int,我們可能會寫出這樣的代碼。

1 class PositiveInteger(int): 2 def __init__(self, value): 3 super(PositiveInteger, self).__init__(self, abs(value)) 4 5 6 i = PositiveInteger(-3) 7 print i

但運行后會發現,結果根本不是我們想的那樣,我們任然得到了-3。這是因為對于int這種 不可變的對象,我們只有重載它的__new__方法才能起到自定義的作用。
這是修改后的代碼:

class PositiveInteger(int):def __new__(cls, value):return super(PositiveInteger, cls).__new__(cls, abs(value))i = PositiveInteger(-3) print i

通過重載__new__方法,我們實現了需要的功能。

2、實現單例

事實上,當我們理解了__new__方法后,我們還可以利用它來做一些其他有趣的事情,比如實現 設計模式中的 單例模式(singleton) 。
因為類每一次實例化后產生的過程都是通過__new__來控制的,所以通過重載__new__方法,我們 可以很簡單的實現單例模式。

class Singleton(object):def __new__(cls):# 關鍵在于這,每一次實例化的時候,我們都只會返回這同一個instance對象if not hasattr(cls, 'instance'):cls.instance = super(Singleton, cls).__new__(cls)return cls.instanceobj1 = Singleton() obj2 = Singleton()obj1.attr1 = 'value1' print obj1.attr1, obj2.attr1 print obj1 is obj2

輸出結果:
value1 value1
True
可以看到obj1和obj2是同一個實例。

class Singleton(object):__instance = Nonedef __init__(self, *args, **kwargs):passdef __new__(cls, *args, **kwargs):if not cls.__instance:# if not hasattr(cls, 'instance'):cls.__instance = super(Singleton, cls).__new__(cls, *args, **kwargs)cls.__instance.aa = args[0]print type(cls), type(cls.__instance), type(cls.__instance.aa)return cls.__instanceobj1 = Singleton(1, 2, 3, b=2) obj2 = Singleton(1, 2, 3, b=2)obj1.attr1 = 'value1' obj2.attr2 = 'value2' print obj1.attr1, obj1.attr2 print obj1 is obj2 print obj1.aa, obj2.attr1

結果:
<type 'type'> <class '__main__.Singleton'> <type 'int'>
value1 value2
True
1 value1

?

3、實現自定義的metaclass。

?

?

參考鏈接:

http://www.cnblogs.com/ifantastic/p/3175735.html

https://my.oschina.net/leejun2005/blog/207371

?

轉載于:https://www.cnblogs.com/cmd61/p/11272834.html

總結

以上是生活随笔為你收集整理的___new__方法和__init__方法的区别的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。