1. 程式人生 > >python中的__new__、__init__和__del__

python中的__new__、__init__和__del__

__new__、__init__、__del__三個方法用於例項的建立和銷燬,在使用python的類中,我們最常用的是__init__方法,通常稱為構造方法,__new__方法幾乎不會使用,這篇文章是基於Python3.6為基礎來做實驗,主要談一談python的__new__和__init__,__init__ 通常稱為構造方法,但其實它是個“初始化方法”,真正的構造方法是 __new__, __init__既然是初始化方法,那麼肯定是對物件的初始化,也就是存在一個被初始化的物件來看第一個例子:

class inch():    def __init__(self):        print("__init__")    def __new__(cls):        print("__new__ ")        print("__new__ ")__new__None

因為我們沒有從__new__返回任何結果,__init__這裡不會呼叫。如果init被呼叫,我們就會看到我們在init中的列印語句。

再看第二個例子:

class inch():    def __new__(cls):        print("__new__ ")        print(super(inch, cls).__new__(cls))         return super(inch, cls).__new__(cls)    def __init__(self):        print("__init__")print(inch())__new__<__main__.inch object at 0x002BF170>__init__<__main__.inch object at 0x002BF170>

用於構建例項的是特殊方法 __new__:是個類方法(不需要使用@classmethod),呼叫 __init__ 方法時要傳入例項,__new__必須返回一個例項。返回的例項會作為第一個引數(即 self)傳給 __init__ 方法。注意:__init__不允許返回任何值

再看第三個列子:

class inch(float):    def __new__(cls, args=0.0):        cls.new = float.__new__(cls,args*0.0254)        return cls.new    def __init__(self,a):        print("__init__")        print(a)object1=inch(3)print(object1.new)__init__30.07619999999999999

 __init__方法中除了self之外定義的引數,都必須與__new__方法中除cls引數之外的引數保持一致

無論我們給超類的__new__傳遞的是哪個類,它都會建立該類的一個例項,如何我們想要建立一個inch的例項,所以,inch類必須作為第一個引數傳遞給float.__new__。在類inch的內部,cls指的是inch類,因此,我們需要將cls作為第一個引數傳遞給物件。

第四個例子:

class B(float):    passclass inch(float):    def __new__(cls, args=0.0):        B.new = float.__new__(B,args*0.0254)        return B.new    def __init__(self,a):        print("__init__")        print(a)object1=inch(3)print(type(object))print(object1.new)<class '__main__.B'>0.0761999999999999

最後:__new__是用來建立一個例項的,從 object 類繼承的已經很完善。所以我們基本上不需要自己編寫 __new__ 方法第四個例子,一個__new__的應用,著名的單例模式(:python 中 None 物件就是單例):

class Singleton:    _instance = None    def __new__(cls, *args, **kwargs):        if not isinstance(cls._instance, cls):            cls._instance = object.__new__(cls, *args, **kwargs)        return cls._instancea=Singleton()b=Singleton()print(a is b)True

__del__:在需要銷燬例項的時候,python直譯器會呼叫__del__方法。Cpython中垃圾回收的主要演算法是引用計數,每個物件會統計有多少引用指向自己。當引用計數歸零時,物件立即就被銷燬