1. 程式人生 > 實用技巧 >Python的內建函式,super()超類用法解析

Python的內建函式,super()超類用法解析

直接用類名呼叫父類方法在使用單繼承的時候沒問題,但是如果使用多繼承,會涉及到查詢順序(MRO)。看到這句話,不太理解,請看這篇文章。

我們在學習 Python 類的時候,總會碰見書上的類中有 __init__() 這樣一個函式,很多同學百思不得其解,其實它就是 Python 的構造方法。

構造方法類似於類似 init() 這種初始化方法,來初始化新建立物件的狀態,在一個物件唄建立以後會立即呼叫,比如像例項化一個類:

f = FooBar()
f.init()
使用構造方法就能讓它簡化成如下形式:
f = FooBar()
你可能還沒理解到底什麼是構造方法,什麼是初始化,下面我們再來舉個例子:
class FooBar:
    def __init__(self):
        self.somevar = 42

>>>f = FooBar()
>>>f.somevar


我們會發現在初始化 FooBar 中的 somevar 的值為 42 之後,例項化直接就能夠呼叫 somevar 的值;如果說你沒有用構造方法初始化值得話,就不能夠呼叫,明白了嗎?

在明白了構造方法之後,我們來點進階的問題,那就是構造方法中的初始值無法繼承的問題。

例子:

class Bird:
    def __init__(self):
          self.hungry = True
    def eat(self):
          if self.hungry:
               print 'Ahahahah'
          else:
               print 'No thanks!'

class SongBird(Bird):
     def __init__(self):
          self.sound = 'Squawk'
     def sing(self):
          print self.song()

sb = SongBird()
sb.sing()    # 能正常輸出
sb.eat()     # 報錯,因為 songgird 中沒有 hungry 特性



那解決這個問題的辦法有兩種:

1、呼叫未繫結的超類構造方法(多用於舊版 python 陣營)

class SongBird(Bird):
     def __init__(self):
          Bird.__init__(self)
          self.sound = 'Squawk'
     def sing(self):
          print self.song()

原理:在呼叫了一個例項的方法時,該方法的self引數會自動繫結到例項上(稱為繫結方法);如果直接呼叫類的方法(比如Bird.__init__),那麼就沒有例項會被繫結,可以自由提供需要的self引數(未繫結方法)。

2、使用super函式(只在新式類中有用)

class SongBird(Bird):
     def __init__(self):
          super(SongBird,self).__init__()
          self.sound = 'Squawk'
     def sing(self):
          print self.song()

原理:它會查詢所有的超類,以及超類的超類,直到找到所需的特性為止。