課時41:魔法方法:構造和析構

那是個好男孩發表於2018-08-24

目錄:

  一、_ _init_ _(self[, ...])

  二、_ _new_ _(cls[, ...])

  三、_ _del_ _(self)

  四、課時41課後習題及答案

 

說的那麼厲害,那什麼是魔法方法呢?

(1)魔法方法總是被雙下劃線包圍,例如_ _init_ _()。

(2)魔法方法是面對物件的Python的一切。

(3)魔法方法的“魔力”體現在它們總能夠在適當的時候被呼叫。

 

**************************

一、_ _init_ _(self[, ...])

**************************

之前我們討論過 _ _init_ _()方法,說它相當於其它物件導向程式語言的構造方法,也就是類在例項化成物件的時候首先會呼叫的一個方法。

也許你會問:“有些時候在定義時寫_ _init_ _()方法,有些時候卻沒有,這是為什麼呢?”舉個例子:

#p12_1.py
class Rectangle:
      """
      定義一個矩形類,
      需要長和寬兩個資料,
      擁有計算周長和麵積的兩個辦法。
      擁有物件在初始化的時候擁有"長"和"寬"兩個引數,
      因此需要重寫_ _init_ _()方法,因為我們說過,
      _ _init_ _()方法是類在例項化成物件的時候首先會呼叫的一個方法,
      """
      def __init__(self,x,y):
            self.x = x
            self.y = y

      def getPeri(self):
            return (self.x + self.y) * 2

      def getArea(self):
            return self.x * self.y
>>> #先執行p12_1.py
>>> rect = Rectangle(3,4)
>>> rect.getPeri()
14
>>> rect.getArea()
12

這裡需要注意的是,_ _init_ _()方法的返回值一定是None,不能是其它:

>>> class A:
    def __init__(self):
        return "A for A - Cup"

    
>>> cup = A()
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    cup = A()
TypeError: __init__() should return None, not 'str'

所以一般在需要進行初始化的時候才重寫__init__()方法。其實,這個__init__()並不是例項化物件時第一個被呼叫的魔法方法。

 

***************************

二、_ _new_ _(cls[, ...])

***************************

_ _new_ _()才是在一個物件例項化的時候所呼叫的第一個方法。它跟其它魔法方法不同,它的第一個引數不是self而時這個類(cls),而其它引數會直接傳遞給_ _init_ _()方法的。

_ _new_ _()方法需要返回一個例項物件,通常是cls這個類例項化的物件,當然你也可以返回其它物件。

_ _new_ _()方法平時很少去重寫它,一般讓Python用預設的方案執行就可以了。但是又一種情況需要重寫這個魔法方法,就是當繼承一個不可變的型別的時候,它的特性就顯得尤為重要了。

>>> class CapStr(str):
    def __new__(cls,string):
        string = string.upper()
        return str.__new__(cls,string)

    
>>> a = CapStr("I love ZWW")
>>> a
'I LOVE ZWW'

這裡返回str.__new__(cls,string)這種做法是值得推崇的,只需要重寫我們關注的那部分內容,然後其它的瑣碎東西交給Python的預設機制去完成就可以了,畢竟它們出錯的機率要比我們自己寫小很多。

 

*********************

三、_ _del_ _(self)

*********************

如果說__init__()和__new__()方法是物件的構造器的話,那麼Python也提供了一個析構器,叫做__del__()方法。當物件將要被銷燬的時候,這個方法就會被呼叫。但一定要注意的是,並非del x就相當於自動呼叫x.__del__(),__del__()方法是當垃圾回收這個物件的時候呼叫的。舉個例子:

>>> class C:
    def __init__(self):
        print("我是__init__()方法,我被呼叫了...")
    def __del__(self):
        print("我是__del__()方法,我被呼叫了...")

        
>>> c1 = C()
我是__init__()方法,我被呼叫了...
>>> c2 = c1
>>> c3 = c2
>>> del c1
>>> del c2
>>> del c3
我是__del__()方法,我被呼叫了...

 

*******************************

四、課時41課後習題及答案

*******************************

 

相關文章