python繼承 python 繼承與多重繼承

2021-10-10 10:51:30 字數 2861 閱讀 8632

當然,如果不支援python繼承,語言特性就不值得稱為「類」。派生類定義的語法如下所示:

名稱 baseclassname 必須定義於包含派生類定義的作用域中。 也允許用其他任意表示式代替基類名稱所在的位置。 這有時也可能會用得上,例如,當基類定義在另乙個模組中的時候:

class derivedclassname(modname.baseclassname):

派生類定義的執行過程與基類相同。 當構造類物件時,基類會被記住。 此資訊將被用來解析屬性引用:如果請求的屬性在類中找不到,搜尋將轉往基類中進行查詢。 如果基類本身也派生自其他某個類,則此規則將被遞迴地應用。

派生類的例項化沒有任何特殊之處: derivedclassname() 會建立該類的乙個新例項。 方法引用將按以下方式解析:搜尋相應的類屬性,如有必要將按基類繼承鏈逐步向下查詢,如果產生了乙個函式物件則方法引用就生效。

在派生類中的過載方法實際上可能想要擴充套件而非簡單地替換同名的基類方法。 有一種方式可以簡單地直接呼叫基類方法:即呼叫 baseclassname.methodname(self, arguments)。 有時這對客戶端來說也是有用的。 (請注意僅當此基類可在全域性作用域中以 baseclassname 的名稱被訪問時方可使用此方式。)

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):

對於多數應用來說,在最簡單的情況下,你可以認為搜尋從父類所繼承屬性的操作是深度優先、從左至右的,當層次結構中存在重疊時不會在同乙個類中搜尋兩次。 因此,如果某一屬性在 derivedclassname 中未找到,則會到 base1 中搜尋它,然後(遞迴地)到 base1 的基類中搜尋,如果在那裡未找到,再到 base2 中搜尋,依此類推。

真實情況比這個更複雜一些;方法解析順序會動態改變以支援對 super() 的協同呼叫。 這種方式在某些其他多重繼承型語言中被稱為後續方法呼叫,它比單繼承型語言中的 super 呼叫更強大。

動態改變順序是有必要的,因為所有多重繼承的情況都會顯示出乙個或更多的菱形關聯(即至少有乙個父類可通過多條路徑被最底層類所訪問)。 例如,所有類都是繼承自 object,因此任何多重繼承的情況都提供了一條以上的路徑可以通向 object。 為了確保基類不會被訪問一次以上,動態演算法會用一種特殊方式將搜尋順序線性化, 保留每個類所指定的從左至右的順序,只呼叫每個父類一次,並且保持單調(即乙個類可以被子類化而不影響其父類的優先順序)。 總而言之,這些特性使得設計具有多重繼承的可靠且可擴充套件的類成為可能。

私有變數

那種僅限從乙個物件內部訪問的「私有」例項變數在 python 中並不存在。 但是,大多數 python **都遵循這樣乙個約定:帶有乙個下劃線的名稱 (例如 _spam) 應該被當作是 api 的非僅供部分 (無論它是函式、方法或是資料成員)。 這應當被視為乙個實現細節,可能不經通知即加以改變。

由於存在對於類私有成員的有效使用場景(例如避免名稱與子類所定義的名稱相衝突),因此存在對此種機制的有限支援,稱為 名稱改寫。 任何形式為 __spam 的識別符號(至少帶有兩個字首下劃線,至多乙個字尾下劃線)的文字將被替換為 _classname__spam,其中 classname 為去除了字首下劃線的當前類名稱。 這種改寫不考慮識別符號的句法位置,只要它出現在類定義內部就會進行。

名稱改寫有助於讓子類過載方法而不破壞類內方法呼叫。例如:

def __init__(self, iterable):

self.items_list =

self.__update(iterable)

def update(self, iterable):

for item in iterable:

__update = update # private copy of original update() method

def update(self, keys, values):

# provides new signature for update()

# but does not break __init__()

for item in zip(keys, values):

請注意,改寫規則的設計主要是為了避免意外衝突;訪問或修改被視為私有的變數仍然是可能的。這在特殊情況下甚至會很有用,例如在偵錯程式中。

請注意傳遞給 exec() 或 eval() 的**不會將發起呼叫類的類名視作當前類;這類似於 global 語句的效果,因此這種效果僅限於同時經過位元組碼編譯的**。 同樣的限制也適用於 getattr(), setattr() 和 delattr(),以及對於 dict 的直接引用。

雜項說明

有時會需要使用類似於 pascal 的「record」或 c 的「struct」這樣的資料型別,將一些命名資料項**在一起。 這種情況適合定義乙個空類:

pass

john = employee() # create an empty employee record

# fill the fields of the record

john.name = "john doe"

john.dept = "computer lab"

john.salary = 1000

例項方法物件也具有屬性: m.__self__ 就是帶有 m() 方法的例項物件,而 m.__func__ 則是該方法所對應的函式物件。

python 多繼承 python 繼承之多繼承

class baserequest pass class requesthandler baserequest def serve forever self print requesthandler.serve forever self.process request def process req...

python怎麼繼承類 python類的繼承

一 概述 二 類的繼承 2.1 繼承的定義 2.2 建構函式的繼承 2.3 子類對父類方法的重寫 三 類繼承的事例 一 概述 物件導向程式設計 oop 語言的乙個主要功能就是 繼承 繼承是指這樣一種能力 它可以使用現有類的所有功能,並在無需重新編寫原來的類的情況下對這些功能進行擴充套件。通過繼承建立...

python類的繼承重構 python類繼承與重構

python類繼承與重構 0 物件 通過類定義的資料結構例項。物件包括兩個資料成員 類變數和例項變數 和方法。usr bin python coding utf 8 class employee 所有員工的基類 empcount 0 def init self,name,salary self.na...