python基礎教程:類的繼承
面嚮物件語言的一個特性就是類的繼承。繼承的關係跟人類繁衍的關係相似,被繼承的類稱為基類(也叫做父類),繼承而得的類叫派生類(也叫子類),這種關係就像人類的父子關係。

類的繼承,說明了不同類直接的關係,派生類複用了基類的程式碼同時也繼承了基類的屬性和方法。派生類定義的語法如下:
派生類的定義
class DerivedClassName(BaseClassName): 語句1 ... 語句n
下面我們根據這個語法來寫一個繼承的例子:
class Person: def __init__(self, name, age, height): self.name = name self.age = age self.height = height def look(self): print(self.name, 'is looking') def walk(self): print(self.name, 'is walking') class Teacher(Person): def __init__(self, name, age, height): super().__init__(name, age, height) def teach(self): print(self.name, 'is teaching') class Student(Person): def __init__(self, name, age, height): super().__init__(name, age, height) def learn(self): print(self.name, 'is learning') if __name__ == '__main__': teacher = Teacher('Tom', 31, 178) s1 = Student('Jim', 12, 160) s2 = Student('Kim', 13, 162) teacher.look() teacher.walk() teacher.teach() print('==='*5) s1.look() s1.walk() s1.learn() print('==='*5) s2.look() s2.walk() s2.learn()
我們定義了一個基類 Person
,這個人有名字(name)、年齡(age)和身高(height)三個屬性,還有 look(), walk()
兩個方法。由它派生出兩個類: Teacher
和 Student
,這兩個派生類繼承了 name, age, height
屬性,也繼承了 look(), walk()
方法。但它們又有自己獨有的方法, Teacher
可以 teach()
, Student
可以 learn()
。
執行這個示例程式碼,可以得到下面的資訊:
Tom is looking Tom is walking Tom is teaching =============== Jim is looking Jim is walking Jim is learning =============== Kim is looking Kim is walking Kim is learning
派生類定義的執行過程與基類相同。 當構造類物件時,基類會被記住。 此資訊將被用來解析屬性引用:如果請求的屬性在類中找不到,搜尋將轉往基類中進行查詢。 如果基類本身也派生自其他某個類,則此規則將被遞迴地應用。
派生類的例項化會建立該類的一個新例項。方法引用將按以下方式解析:搜尋相應的類屬性,如果搜尋的方法在派生類中找不到,就去基類中進行查詢,如果基類本身也派生自其它類,則此規則將被遞迴地應用。如果搜尋到了一個函式物件則方法引用就生效。
比如, Teacher
中並沒有定義 look()
,當我們呼叫方法 teacher.look()
的時候會在它的基類 Person
中找到並呼叫 look()
。
過載基類方法
派生類可以過載基類的方法。過載,就是重新定義。如果派生類中重新定義了基類的某方法,那麼派生類的過載的這個方法就會覆蓋基類中的同名方法。
例如,我們定義 Student
時可以過載 walk()
方法,讓它擁有 Student
特徵:
class Student(Person): def __init__(self, name, age, height): super().__init__(name, age, height) def learn(self): print(self.name, 'is learning') def walk(self): print('Student:', self.name, 'is walking')
再次執行 s1.walk()
時,就會列印下面的資訊:
Student: Jim is walking
Python有兩個內建函式可被用於檢查繼承機制:
-
isinstance()
來檢查一個例項的型別:isinstance(obj, int)
僅僅會在obj.__class__
為int
或某個派生自int
的類時為True。 -
issubclass()
來檢查類的繼承關係:issubclass(bool, int)
為True
,因為bool
是int
的子類。但是,issubclass(float, int)
為False
,因為float
不是int
的子類。
多重繼承
多重繼承的意思就是,一個派生類同時派生自多個基類,繼承它們全部屬性和方法。它的定義形式是:
class DerivedClassName(Base1, Base2, Base3): 語句1 ... 語句1
對於多數應用來說,在最簡單的情況下,你可以認為搜尋從父類所繼承屬性的操作是深度優先、從左至右的,當層次結構中存在重疊時不會在同一個類中搜索兩次。 因此,如果某一屬性在 DerivedClassName 中未找到,則會到 Base1 中搜索它,然後(遞迴地)到 Base1 的基類中搜索,如果在那裡未找到,再到 Base2 中搜索,依此類推。
真實情況比這個更復雜一些;方法解析順序會動態改變以支援對 super() 的協同呼叫。 這種方式在某些其他多重繼承型語言中被稱為後續方法呼叫,它比單繼承型語言中的 super 呼叫更強大。
比如,我們要定義一個“助教”類,助教是幫助老師教學的高年級同學。他兼具老師和學生的特點,我們可以讓這個類多重繼承“老師類”和“學生類”。
私有變數
我們上一節講過,Python中沒有類似C++中的“私有變數”。但是,大多數Python程式碼都遵循這樣一個約定(只是約定但很重要):帶有一個下劃線的名稱(例如: _name
)應當被動作是API的非僅供部分(無論它是函式、方法或是資料成員)。 這應當被視為一個實現細節,可能不經通知即加以改變。
由於存在對於類私有成員的有效使用場景(例如避免名稱與子類所定義的名稱相沖突),因此存在對此種機制的有限支援,稱為 名稱改寫 。 任何形式為 __name
的識別符號(至少帶有兩個字首下劃線,至多一個字尾下劃線)的文字將被替換為 _classname__name
,其中 classname
為去除了字首下劃線的當前類名稱。這種改寫不考慮識別符號的句法位置,只要它出現在類定義內部就會進行。
名稱改寫有助於讓子類過載方法而不破壞類內方法呼叫。例如:
class MyList: def __init__(self, iterable): self.items_list = [] self.__update(iterable) def update(self, iterable): for item in iterable: self.items_list.append(item) __update = update# 把update()拷貝給私有方法 class MyListSubclass(MyList): def update(self, keys, values): # 過載 update() # 但不會破壞 __init__() for item in zip(keys, values): self.items_list.append(item)
這個示例中即使正在 MyListSubclass
引入一個 __update
識別符號的情況下也不會出錯,因為它會在 MyList
類中被替換為 _MyList__update
,而在 MyListSubclass
類中被替換為 _MyListSubclass__update
。
改寫規則的設計主要是為了避免意外衝突;訪問或修改被視為私有的變數仍然是可能的。這在特殊情況下甚至會很有用,例如在偵錯程式中。
請注意傳遞給 exec() 或 eval() 的程式碼不會將發起呼叫類的類名視作當前類;這類似於 global 語句的效果,因此這種效果僅限於同時經過位元組碼編譯的程式碼。 同樣的限制也適用於 getattr(), setattr() 和 delattr(),以及對於 dict 的直接引用。
總結
類的繼承體現了類的關係,基類的屬性和方法可以被派生類繼承,同時派生類又可以過載基類的方法。派生類既可以單獨繼承一個基類,也可以多重繼承多個基類。Python的類沒有真正意義上的私有變數,通過約定和名稱改寫來有限支援私有變數。
大家在學python的時候肯定會遇到很多難題,以及對於新技術的追求,這裡推薦一下我們的Python學習扣qun:784758214,這裡是python學習者聚集地!!同時,自己是一名高階python開發工程師,從基礎的python指令碼到web開發、爬蟲、django、資料探勘等,零基礎到專案實戰的資料都有整理。送給每一位python的小夥伴!每日分享一些學習的方法和需要注意的小細節
