python異常繼承樹,python超繼承

本文目錄一覽:

Python類的繼承和多態代碼詳解

Python類的繼承和多態代碼詳解

Python類的繼承

在OOP(ObjectOrientedProgramming)程序設計中,當我們定義一個class的時候,可以從某個現有的class繼承,新的class稱為子類(Subclass),而被繼承的class稱為基類、父類或超類(Baseclass、Superclass)。

我們先來定義一個classPerson,表示人,定義屬性變數name及sex(姓名和性別);

定義一個方法print_title():當sex是male時,printman;當sex是female時,printwoman。參考如下代碼:

class Person(object):

def __init__(self,name,sex):

self.name = name

self.sex = sex

def print_title(self):

if self.sex == “male”:

print(“man”)

elif self.sex == “female”:

print(“woman”)

class Child(Person): # Child 繼承 Person

pass

May = Child(“May”,”female”)

Peter = Person(“Peter”,”male”)

print(May.name,May.sex,Peter.name,Peter.sex) # 子類繼承父類方法及屬性

May.print_title()

Peter.print_title()

而我們編寫Child類,完全可以繼承Person類(Child就是Person);使用classsubclass_name(baseclass_name)來表示繼承;

繼承有什麼好處?最大的好處是子類獲得了父類的全部屬性及功能。如下Child類就可以直接使用父類的print_title()方法

實例化Child的時候,子類繼承了父類的構造函數,就需要提供父類Person要求的兩個屬性變數name及sex:

在繼承關係中,如果一個實例的數據類型是某個子類,那它也可以被看做是父類(May既是Child又是Person)。但是,反過來就不行(Peter僅是Person,而不是Child)。

繼承還可以一級一級地繼承下來,就好比從爺爺到爸爸、再到兒子這樣的關係。而任何類,最終都可以追溯到根類object,這些繼承關係看上去就像一顆倒著的樹。比如如下的繼承樹:

isinstance()及issubclass()

Python與其他語言不同點在於,當我們定義一個class的時候,我們實際上就定義了一種數據類型。我們定義的數據類型和Python自帶的數據類型,比如str、list、dict沒什麼兩樣。

Python有兩個判斷繼承的函數:isinstance()用於檢查實例類型;issubclass()用於檢查類繼承。參見下方示例:

class Person(object):

pass

class Child(Person): # Child 繼承 Person

pass

May = Child()

Peter = Person()

print(isinstance(May,Child)) # True

print(isinstance(May,Person)) # True

print(isinstance(Peter,Child)) # False

print(isinstance(Peter,Person)) # True

print(issubclass(Child,Person)) # True

Python類的多態

在說明多態是什麼之前,我們在Child類中重寫print_title()方法:若為male,printboy;若為female,printgirl

class Person(object):

def __init__(self,name,sex):

self.name = name

self.sex = sex

def print_title(self):

if self.sex == “male”:

print(“man”)

elif self.sex == “female”:

print(“woman”)

class Child(Person): # Child 繼承 Person

def print_title(self):

if self.sex == “male”:

print(“boy”)

elif self.sex == “female”:

print(“girl”)

May = Child(“May”,”female”)

Peter = Person(“Peter”,”male”)

print(May.name,May.sex,Peter.name,Peter.sex)

May.print_title()

Peter.print_title()

當子類和父類都存在相同的print_title()方法時,子類的print_title()覆蓋了父類的print_title(),在代碼運行時,會調用子類的print_title()

這樣,我們就獲得了繼承的另一個好處:多態。

多態的好處就是,當我們需要傳入更多的子類,例如新增Teenagers、Grownups等時,我們只需要繼承Person類型就可以了,而print_title()方法既可以直不重寫(即使用Person的),也可以重寫一個特有的。這就是多態的意思。調用方只管調用,不管細節,而當我們新增一種Person的子類時,只要確保新方法編寫正確,而不用管原來的代碼。這就是著名的「開閉」原則:

對擴展開放(Openforextension):允許子類重寫方法函數

對修改封閉(Closedformodification):不重寫,直接繼承父類方法函數

子類重寫構造函數

子類可以沒有構造函數,表示同父類構造一致;子類也可重寫構造函數;現在,我們需要在子類Child中新增兩個屬性變數:mother和father,我們可以構造如下(建議子類調用父類的構造方法,參見後續代碼):

class Person(object):

def __init__(self,name,sex):

self.name = name

self.sex = sex

class Child(Person): # Child 繼承 Person

def __init__(self,name,sex,mother,father):

self.name = name

self.sex = sex

self.mother = mother

self.father = father

May = Child(“May”,”female”,”April”,”June”)

print(May.name,May.sex,May.mother,May.father)

Person

若父類構造函數包含很多屬性,子類僅需新增1、2個,會有不少冗餘的代碼,這邊,子類可對父類的構造方法進行調用,參考如下:

class Person(object):

def __init__(self,name,sex):

self.name = name

self.sex = sex

class Child(Person): # Child 繼承 Person

def __init__(self,name,sex,mother,father):

Person.__init__(self,name,sex) # 子類對父類的構造方法的調用

self.mother = mother

self.father = father

May = Child(“May”,”female”,”April”,”June”)

print(May.name,May.sex,May.mother,May.father)

多重繼承

多重繼承的概念應該比較好理解,比如現在需要新建一個類baby繼承Child,可繼承父類及父類上層類的屬性及方法,優先使用層類近的方法,代碼參考如下:

class Person(object):

def __init__(self,name,sex):

self.name = name

self.sex = sex

def print_title(self):

if self.sex == “male”:

print(“man”)

elif self.sex == “female”:

print(“woman”)

class Child(Person):

pass

class Baby(Child):

pass

May = Baby(“May”,”female”) # 繼承上上層父類的屬性

print(May.name,May.sex)

May.print_title() # 可使用上上層父類的方法

class Child(Person):

def print_title(self):

if self.sex == “male”:

print(“boy”)

elif self.sex == “female”:

print(“girl”)

class Baby(Child):

pass

May = Baby(“May”,”female”)

May.print_title() # 優先使用上層類的方法

總結

以上就是本文關於Python類的繼承和多態代碼詳解的全部內容,希望對大家有所幫助。

Python 實現slots的繼承

__slots__ 是python的一大神器。

它有兩大的特點:

python文檔中這樣介紹它

首先第一點,python的動態性一部分源自於 __dict__ ,屬性都保存在 __dict__ 的一個字典中,我們可以隨時向這個字典添加新內容,這是 MonkeyPatch 的能力。

而當我們顯示的聲明了 __slots__ ,python將不會給這個類創建 __dict__ 和 __weakref__

沒有了 __dict__ 我們便不能隨意創建實例屬性,而必須遵守 __slots__ 的約定。

對於性能而言,使用了 __slots__ 後,屬性會直接存儲到對象中,而不是 __dict__ 中,相當於少了一次檢索步驟。

__slots__ 的兩大優點,對於python來說,是難以拒絕的誘惑。既能限制不必要的動態性,又能提高性能!

但是 __slots__ 遇到繼承時,就會出現很多問題。準確的說, __slots__ 不會被繼承。當我們用一個不帶有 __slots__ 的子類,繼承帶有 __slots__ 的父類時。子類還是會生成 __dict__ 和 __weakref__ 。

這是之前寫的一個metaclass,創建新的類對象時,會進行以下邏輯。

實際上我們的目的正是解決,父類規定的 __slots__ 約束不了無 __slots__ 子類的問題。這個結果令人非常滿意

注意這裡子類的d,在 pycharm 等IDE中不會提示錯誤,因為 pycharm 無法探知你的metaclass做了這樣 逆天改命 的邏輯。

需要注意一點, __slots__ 是 類對實例屬性的約束 ,而類對象無法通過該屬性,約束自己。即為類對象添加新屬性,仍然是被允許的。

按照正常思路,也許我們應該到metaclass寫一個 __slots__ ,但實際上這是不被允許的。

抽空找時間我會考慮下有無可行性。

說說 Python 的繼承

如果要編寫的類是另一個類的特殊版本時,那麼就可以使用繼承 。原有的類稱為父類 , 新類稱為子類 。 子類繼承了父類的所有屬性和方法, 同時子類還可以自定義自己的屬性和方法。

定義子類的實例時, 可以通過 子類的 __init__() 方法,給父類的所有屬性賦值。

假設有這樣的一個 User 類:

接著,我們定義一個 Admin 類,讓它繼承 User 類:

運行結果:

super() 是一個特殊函數, 它會把父類和子類關聯起來。因為父類也稱為超類 ( superclass),所以這個函數叫做 super。接著調用父類的 __init__() 方法, 讓子類包含父類的所有屬性。

子類除了擁有繼承父類而來的屬性和方法之外,還可以自定義子類自己的屬性和方法。

一般情況下,管理員賬號比普通賬號,擁有更高級別的許可權。因此,我們為 Admin 定義一個有別於 User 的 privileges 屬性,並定義一個 「列印擁有的許可權」 的新方法:

運行結果:

對於繼承而來的父類方法, 如果它不符合子類所期望的行為,那麼就可以對其重寫。 只要在子類中定義一個與父類同名的方法,即可實現重寫。

User 本身定義了一個 「是否驗證通過」 的方法,Admin 是管理員,所以需要在列印日誌中特別標註出來,這時就需要重寫父類定義的方法:

運行結果:

通過重寫父類方法, 我們就可以讓子類即可以保留或改寫從父類取其精華,棄其「糟粕」啦。

當實體越來越複雜,對應的類變得越來越大時, 我們可以將這個大型類拆分成多個可協同工作的小類。

比如,賬號許可權,其實即使是普通賬號也是有某些許可權的。所以我們把許可權定義為一個類,然後在 Admin 中使用它:

python有關類繼承的問題

子類繼承父類就是在父類部分的基礎上加上一些子類擴展的屬性、方法以及重寫的父類方法。所以構造一個子類對象時要先構造它的父類部分,構造父類部分就需要調用父類的構造函數。

python拋出異常如何操作?

8.4. 拋出異常

raise 語句允許程序員強制拋出一個指定的異常。例如:

raise NameError(‘HiThere’)

Traceback (most recent call last):

File “

“, line 1, in ?

NameError: HiThere

要拋出的異常由 raise 的唯一參數標識。它必需是一個異常實例或異常類(繼承自 Exception 的類)。

如果你需要明確一個異常是否拋出,但不想處理它,raise 語句可以讓你很簡單的重新拋出該異常:

try:

… raise NameError(‘HiThere’)

… except NameError:

… print(‘An exception flew by!’)

… raise

An exception flew by!

Traceback (most recent call last):

File “

“, line 2, in ?

NameError: HiThere

原創文章,作者:LQZP,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/137521.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
LQZP的頭像LQZP
上一篇 2024-10-04 00:17
下一篇 2024-10-04 00:17

相關推薦

  • Python中引入上一級目錄中函數

    Python中經常需要調用其他文件夾中的模塊或函數,其中一個常見的操作是引入上一級目錄中的函數。在此,我們將從多個角度詳細解釋如何在Python中引入上一級目錄的函數。 一、加入環…

    編程 2025-04-29
  • Python計算陽曆日期對應周幾

    本文介紹如何通過Python計算任意陽曆日期對應周幾。 一、獲取日期 獲取日期可以通過Python內置的模塊datetime實現,示例代碼如下: from datetime imp…

    編程 2025-04-29
  • Python列表中負數的個數

    Python列表是一個有序的集合,可以存儲多個不同類型的元素。而負數是指小於0的整數。在Python列表中,我們想要找到負數的個數,可以通過以下幾個方面進行實現。 一、使用循環遍歷…

    編程 2025-04-29
  • 如何查看Anaconda中Python路徑

    對Anaconda中Python路徑即conda環境的查看進行詳細的闡述。 一、使用命令行查看 1、在Windows系統中,可以使用命令提示符(cmd)或者Anaconda Pro…

    編程 2025-04-29
  • Python周杰倫代碼用法介紹

    本文將從多個方面對Python周杰倫代碼進行詳細的闡述。 一、代碼介紹 from urllib.request import urlopen from bs4 import Bea…

    編程 2025-04-29
  • Python字典去重複工具

    使用Python語言編寫字典去重複工具,可幫助用戶快速去重複。 一、字典去重複工具的需求 在使用Python編寫程序時,我們經常需要處理數據文件,其中包含了大量的重複數據。為了方便…

    編程 2025-04-29
  • Python清華鏡像下載

    Python清華鏡像是一個高質量的Python開發資源鏡像站,提供了Python及其相關的開發工具、框架和文檔的下載服務。本文將從以下幾個方面對Python清華鏡像下載進行詳細的闡…

    編程 2025-04-29
  • 蝴蝶優化演算法Python版

    蝴蝶優化演算法是一種基於仿生學的優化演算法,模仿自然界中的蝴蝶進行搜索。它可以應用於多個領域的優化問題,包括數學優化、工程問題、機器學習等。本文將從多個方面對蝴蝶優化演算法Python版…

    編程 2025-04-29
  • python強行終止程序快捷鍵

    本文將從多個方面對python強行終止程序快捷鍵進行詳細闡述,並提供相應代碼示例。 一、Ctrl+C快捷鍵 Ctrl+C快捷鍵是在終端中經常用來強行終止運行的程序。當你在終端中運行…

    編程 2025-04-29
  • Python程序需要編譯才能執行

    Python 被廣泛應用於數據分析、人工智慧、科學計算等領域,它的靈活性和簡單易學的性質使得越來越多的人喜歡使用 Python 進行編程。然而,在 Python 中程序執行的方式不…

    編程 2025-04-29

發表回復

登錄後才能評論