python數(shù)據(jù)結(jié)構(gòu)之面向?qū)ο?/h1>
更新時(shí)間:2022年01月25日 10:12:27 作者:柳小蔥
這篇文章主要介紹了python數(shù)據(jù)結(jié)構(gòu)之面向?qū)ο?,在python數(shù)據(jù)結(jié)構(gòu)的上一章節(jié)我們講述了python的輸入輸出控制異常,希望大家重點(diǎn)掌握輸出和控制,這些都是比較簡(jiǎn)單的啦,多看看就好了,接下來(lái)我們要講的是python面向?qū)ο?需要的朋友可以參考一下
前文學(xué)習(xí):
python數(shù)據(jù)結(jié)構(gòu):數(shù)據(jù)類(lèi)型.
python數(shù)據(jù)結(jié)構(gòu)輸入輸出及控制和異常.
今天我們來(lái)學(xué)習(xí)面向?qū)ο缶幊蹋嫦驅(qū)ο筮@種編程方式非常重要,我們以后學(xué)習(xí)到的棧、隊(duì)列、鏈表都是通過(guò)面向?qū)ο蟮姆绞綄?shí)現(xiàn)的。
1. 面向?qū)ο缶幊?/h2>
定義:面向?qū)ο笫前凑杖藗兛陀^世界的系統(tǒng)思維方式,采用基于對(duì)象(實(shí)體)的概念建立模型 ,模擬客觀世界分析,設(shè)計(jì),實(shí)現(xiàn)軟件的辦法。通過(guò)面向?qū)ο蟮睦砟钍褂?jì)算機(jī)軟件系統(tǒng)能與現(xiàn)實(shí)世界中的系統(tǒng)的一一對(duì)應(yīng)。
聽(tīng)到這很多同學(xué)應(yīng)該會(huì)很蒙,我解釋一下幾個(gè)關(guān)鍵詞的概念:
- 對(duì)象:一切事物都可以是對(duì)象,更準(zhǔn)確的說(shuō),對(duì)象是一個(gè)實(shí)體,用一組可識(shí)別的特征和行為來(lái)標(biāo)識(shí),可以說(shuō)對(duì)象不同的地方就是具有不同的特征與行為。
- 類(lèi):是具有相同屬性和功能的對(duì)象抽象集合
實(shí)例:就是創(chuàng)建具體對(duì)象的過(guò)程
舉一個(gè)面向?qū)ο蟮睦樱何覀冃枰煲惠v車(chē),我們可能并不需要知道車(chē)的原理,我們只需要找到車(chē)的輪子,車(chē)的車(chē)架,車(chē)的發(fā)動(dòng)機(jī),然后將它們拼裝在一起即可。
在前面我們已經(jīng)使用了一些內(nèi)建的類(lèi)來(lái)展示數(shù)據(jù)和控制結(jié)構(gòu)的例子。面向?qū)ο缶幊陶Z(yǔ)言最強(qiáng)大的一項(xiàng)特性是允許程序員(問(wèn)題求解者) 創(chuàng)建全新的類(lèi)來(lái)對(duì)求解問(wèn)題所需的數(shù)據(jù)進(jìn)行建模。
我們之前使用了抽象數(shù)據(jù)類(lèi)型來(lái)對(duì)數(shù)據(jù)對(duì)象的狀態(tài)及行為進(jìn)行邏輯描述。通過(guò)構(gòu)建能實(shí)現(xiàn)抽象數(shù)據(jù)類(lèi)型的類(lèi),可以利用抽象過(guò)程,同時(shí)為真正在程序中運(yùn)用抽象提供必要的細(xì)節(jié)。每當(dāng)需要實(shí)現(xiàn)抽象數(shù)據(jù)類(lèi)型時(shí),就可以創(chuàng)建新類(lèi)。
2. 構(gòu)建類(lèi)
我們來(lái)構(gòu)建一個(gè)分?jǐn)?shù)類(lèi)fraction類(lèi):

你這不能用除法?其實(shí)是可以,但是除法的方式python已經(jīng)有自己的類(lèi)了,我這里需要自己創(chuàng)建一個(gè)分?jǐn)?shù)類(lèi)。
所有類(lèi)都應(yīng)該首先提供構(gòu)造方法。構(gòu)造方法定義了數(shù)據(jù)對(duì)象的創(chuàng)建方式。要?jiǎng)?chuàng)建 Fraction 類(lèi)的實(shí)例,必須調(diào)用構(gòu)造方法,要?jiǎng)?chuàng)建一個(gè) Fraction 對(duì)象,需要提供分子和分母兩部分?jǐn)?shù)據(jù)。
class fraction: #定義一個(gè)類(lèi)
def __init__(self,top,bottom):#定義構(gòu)造方法 __init__
self.num=top
self.den=bottom
這里解釋一下,self 是一個(gè)總是指向?qū)ο蟊旧淼奶厥鈪?shù),它必須是第一 個(gè)形式參數(shù)。然而,在調(diào)用方法時(shí),從來(lái)不需要提供相應(yīng)的實(shí)際參數(shù)。如前所述,分?jǐn)?shù)需要分子與分母兩部分狀態(tài)數(shù)據(jù)。構(gòu)造方法中的 self.num 定義了 Fraction 對(duì)象有一個(gè)叫作 num 的內(nèi)部數(shù)據(jù)對(duì)象作為其狀態(tài)的一部分。同理,self.den 定義了分母。這兩個(gè)實(shí)際參數(shù)的值在初始時(shí),賦給了狀態(tài),使得新創(chuàng)建的 Fraction 對(duì)象能夠知道其初始值。
class fraction: #定義一個(gè)類(lèi)
def __init__(self,top,bottom):#定義構(gòu)造方法 __init__
self.num=top
self.den=bottom
myfraction = fraction(3,5)#使用類(lèi)創(chuàng)建一個(gè)對(duì)象。
我們可以用下面這個(gè)圖來(lái)描述,我們構(gòu)造類(lèi)一個(gè)類(lèi),然后通過(guò)類(lèi)創(chuàng)建了一個(gè)對(duì)象。

一般情況下,我們定義了一個(gè)類(lèi),里面會(huì)有這個(gè)類(lèi)的一些方法,例如,我要查看這個(gè)分?jǐn)?shù)對(duì)象的樣子,我要計(jì)算這中類(lèi)型的分?jǐn)?shù),等等方法,這些都需要我們?nèi)ザx。
class fraction: #定義一個(gè)類(lèi)
def __init__(self,top,bottom):#定義構(gòu)造方法 __init__
self.num=top
self.den=bottom
def show(self): #定義輸出方法
print(self.num,"/",self.den)
def add(self,otherf): #定義分?jǐn)?shù)加法
bot=otherf.den * self.den
top=self.num * otherf.den +self.den * otherf.num
print(top,"/",bot)
#定義兩個(gè)分?jǐn)?shù)
myfraction=fraction(9,16)
a=fraction(1,16)
#試試加法
myfraction.add(a)
結(jié)果如下:

這里我們放上我們寫(xiě)好的分?jǐn)?shù)類(lèi)定義方法。
class Fraction:
def __init__(self, top, bottom):
self.num = top
self.den = bottom
def __str__(self):
return str(self.num) + "/" + str(self.den)
def show(self):
print(self.num, "/", self.den)
def __add__(self, otherfraction): #加法 ,可以用+
newnum = self.num * otherfraction.den + self.den * otherfraction.num
newden = self.den * otherfraction.den
common = gcd(newnum, newden)
return Fraction(newnum//common, newden//common)
def __eq__(self, other): #深相等,值相等就相等
firstnum = self.num * other.den
secondnum = other.num * self.den
return firstnum == secondnum
3. 繼承
繼承是面向?qū)ο缶幊痰囊粋€(gè)重要特征:使一個(gè)類(lèi)與另一個(gè)類(lèi)相關(guān)聯(lián),就像人們相互聯(lián)系一樣。孩子從父母那里繼承了特征,python的子類(lèi)可以從父類(lèi)那繼承數(shù)據(jù)和行為,父類(lèi)也稱(chēng)為超類(lèi)。
就拿我們前面學(xué)習(xí)過(guò)的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)舉例。

列表、字符串和元組都是有序集合。它們都繼承了共同的數(shù)據(jù)組織和操作。不過(guò),根據(jù)數(shù)據(jù)是否同類(lèi)以及集合是否可修改,它們彼此又有區(qū)別。子類(lèi)從父類(lèi)繼承共同的特征,但是通過(guò)額外的特征彼此區(qū)分。
3.1 繼承案例
我們這里通過(guò)一個(gè)小的案例來(lái)實(shí)現(xiàn)繼承的案例,我們來(lái)構(gòu)建一個(gè)模擬程序,用于模擬數(shù)字電路。邏輯門(mén)是這個(gè)模擬程序的基本構(gòu)造單元,它們代表其輸入和輸出之間的布爾代數(shù)關(guān)系。

通過(guò)不同的模式將這些邏輯門(mén)組合起來(lái)并提供一系列輸入值,可以構(gòu)建具有邏輯功能的電 路。圖 1-10 展示了一個(gè)包含兩個(gè)與門(mén)、一個(gè)或門(mén)和一個(gè)非門(mén)的電路。兩個(gè)與門(mén)的輸出直接作為 輸入傳給或門(mén),然后其輸出又輸入給非門(mén)。如果在 4 個(gè)輸入處(每個(gè)與門(mén)有兩個(gè)輸入)提供一系列值,那么非門(mén)就會(huì)輸出結(jié)果。

為了實(shí)現(xiàn)電路,首先需要構(gòu)建邏輯門(mén)的表示??梢暂p松地將邏輯門(mén)組織成類(lèi)的繼承層次結(jié)構(gòu), 如圖所示。頂部的 LogicGate 類(lèi)代表邏輯門(mén)的通用特性:邏輯門(mén)的標(biāo)簽和一個(gè)輸出。下面 一層子類(lèi)將邏輯門(mén)分成兩種:有一個(gè)輸入的邏輯門(mén)和有兩個(gè)輸入的邏輯門(mén)。再往下,就是具體的邏輯門(mén)。

首先定義父類(lèi)LogicGate
class LogicGate:
def __init__(self, n):#構(gòu)造函數(shù),label代表的是自己的名字
self.label = n
self.output = None
def getLabel(self):#輸出名字的函數(shù)
return self.label
def getOutput(self):#輸出的結(jié)果
self.output = self.performGateLogic()
return self.output
目前還不用實(shí)現(xiàn) performGateLogic 函數(shù)。原因在于,我們不知道每一種邏輯門(mén)將如何進(jìn) 行自己的邏輯運(yùn)算。這些細(xì)節(jié)會(huì)交由繼承層次結(jié)構(gòu)中的每一個(gè)邏輯門(mén)來(lái)實(shí)現(xiàn)。這是一種在面向?qū)ο缶幊讨蟹浅?qiáng)大的思想——我們創(chuàng)建了一個(gè)方法,而其代碼還不存在。參數(shù) self 是指向?qū)嶋H調(diào)用方法的邏輯門(mén)對(duì)象的引用。任何添加到繼承層次結(jié)構(gòu)中的新邏輯門(mén)都僅需要實(shí)現(xiàn)之后會(huì)被調(diào)用的 performGateLogic 函數(shù)。一旦實(shí)現(xiàn)完成,邏輯門(mén)就可以提供運(yùn)算結(jié)果。擴(kuò)展已有的繼承層次結(jié)構(gòu)并提供使用新類(lèi)所需的特定函數(shù),這種能力對(duì)于重用代碼來(lái)說(shuō)非常重要。
定義子類(lèi)BinaryGate類(lèi)、UnaryGate類(lèi)
兩個(gè)類(lèi)中的構(gòu)造方法首先使用 super 函數(shù) 來(lái)調(diào)用其父類(lèi)的構(gòu)造方法。當(dāng)創(chuàng)建 BinaryGate 類(lèi)的實(shí)例時(shí),首先要初始化所有從LogicGate 中繼承來(lái)的數(shù)據(jù)項(xiàng),在這里就是邏輯門(mén)的標(biāo)簽。接著,構(gòu)造方法添加兩個(gè)輸入(pinA 和 pinB)。 這是在構(gòu)建類(lèi)繼承層次結(jié)構(gòu)時(shí)常用的模式。子類(lèi)的構(gòu)造方法需要先調(diào)用父類(lèi)的構(gòu)造方法,然后再 初始化自己獨(dú)有的數(shù)據(jù)。
BinaryGate類(lèi)主要是與門(mén)和或門(mén)(有兩個(gè)輸入)
class BinaryGate(LogicGate):
def __init__(self, n):
super().__init__(n)#繼承父類(lèi)的構(gòu)造方法
self.pinA = None #添加自己的參數(shù)
self.pinB = None
def getPinA(self):#自己的方法
return int(input("Enter Pin A input for gate "+self.getLabel() + "-->"))
def getPinB(self):#自己的方法
return int(input("Enter Pin B input for gate "+self.getLabel() + "-->"))
UnaryGate類(lèi)主要是非門(mén)(只有一個(gè)輸入)。
class UnaryGate(LogicGate):
def __init__(self, n):
super().__init__(n)#繼承父類(lèi)的構(gòu)造方法
self.pin = None#添加自己的參數(shù)
def getPin(self):#自己的方法
return int(input("Enter Pin input for gate " + self.getLabel() + "-->"))
構(gòu)造孫類(lèi)(與門(mén)、或門(mén)、非門(mén))
與門(mén) AndGate類(lèi)
#構(gòu)造與門(mén)
class AndGate(BinaryGate):
def __init__(self, n):
super().__init__(n)#繼承父類(lèi)方法
def performGateLogic(self):#自己的運(yùn)算邏輯
a = self.getPinA()
b = self.getPinB()
if a==1 and b==1:
return 1
else:
return 0
或門(mén) OrGate
class OrGate(BinaryGate):
def __init__(self, n):
super().__init__(n)#繼承父類(lèi)方法
def performGateLogic(self):
a = self.getPinA()
b = self.getPinB()
if a==1 or b==1:
return 1
else:
return 0
非門(mén) NotGate
class NotGate(UnaryGate):
def __init__(self, n):
super().__init__(n)
def performGateLogic(self):
a = self.getPin()
if a==1:
return 0
else:
return 1
測(cè)試一下結(jié)果:
與門(mén)

或門(mén)

非門(mén)

參考資料:
- 《python數(shù)據(jù)結(jié)構(gòu)與算法》
- 《大話(huà)數(shù)據(jù)結(jié)構(gòu)》
到此這篇關(guān)于python數(shù)據(jù)結(jié)構(gòu)之面向?qū)ο蟮奈恼戮徒榻B到這了,更多相關(guān)python面向?qū)ο髢?nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
-
詳解Python實(shí)現(xiàn)字典合并的四種方法
這篇文章主要為大家詳細(xì)介紹了Python的合并字典的四種方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助 2022-03-03
-
Python?PaddleNLP開(kāi)源實(shí)現(xiàn)快遞單信息抽取
這篇文章主要為大家介紹了Python?PaddleNLP開(kāi)源項(xiàng)目實(shí)現(xiàn)對(duì)快遞單信息抽取,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪 2022-06-06
-
python實(shí)現(xiàn)按行切分文本文件的方法
這篇文章主要介紹了python實(shí)現(xiàn)按行切分文本文件的方法,涉及Python利用shell命令操作文本文件的相關(guān)技巧,需要的朋友可以參考下 2016-04-04
-
python [::-1] [::-1,::-1]的具體使用
本文主要介紹了python [::-1] [::-1,::-1]的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧 2022-05-05
-
利用pyecharts實(shí)現(xiàn)地圖可視化的例子
今天小編就為大家分享一篇利用pyecharts實(shí)現(xiàn)地圖可視化的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧 2019-08-08
-
Python Sympy計(jì)算梯度、散度和旋度的實(shí)例
今天小編就為大家分享一篇Python Sympy計(jì)算梯度、散度和旋度的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧 2019-12-12
-
Django import export實(shí)現(xiàn)數(shù)據(jù)庫(kù)導(dǎo)入導(dǎo)出方式
這篇文章主要介紹了Django import export實(shí)現(xiàn)數(shù)據(jù)庫(kù)導(dǎo)入導(dǎo)出方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧 2020-04-04
-
request基本使用及各種請(qǐng)求方式參數(shù)的示例
這篇文章主要為大家介紹了request的基本使用及各種請(qǐng)求方式參數(shù)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪 2022-04-04
最新評(píng)論
前文學(xué)習(xí):
python數(shù)據(jù)結(jié)構(gòu):數(shù)據(jù)類(lèi)型.
python數(shù)據(jù)結(jié)構(gòu)輸入輸出及控制和異常.
今天我們來(lái)學(xué)習(xí)面向?qū)ο缶幊蹋嫦驅(qū)ο筮@種編程方式非常重要,我們以后學(xué)習(xí)到的棧、隊(duì)列、鏈表都是通過(guò)面向?qū)ο蟮姆绞綄?shí)現(xiàn)的。
1. 面向?qū)ο缶幊?/h2>
定義:面向?qū)ο笫前凑杖藗兛陀^世界的系統(tǒng)思維方式,采用基于對(duì)象(實(shí)體)的概念建立模型 ,模擬客觀世界分析,設(shè)計(jì),實(shí)現(xiàn)軟件的辦法。通過(guò)面向?qū)ο蟮睦砟钍褂?jì)算機(jī)軟件系統(tǒng)能與現(xiàn)實(shí)世界中的系統(tǒng)的一一對(duì)應(yīng)。
定義:面向?qū)ο笫前凑杖藗兛陀^世界的系統(tǒng)思維方式,采用基于對(duì)象(實(shí)體)的概念建立模型 ,模擬客觀世界分析,設(shè)計(jì),實(shí)現(xiàn)軟件的辦法。通過(guò)面向?qū)ο蟮睦砟钍褂?jì)算機(jī)軟件系統(tǒng)能與現(xiàn)實(shí)世界中的系統(tǒng)的一一對(duì)應(yīng)。
聽(tīng)到這很多同學(xué)應(yīng)該會(huì)很蒙,我解釋一下幾個(gè)關(guān)鍵詞的概念:
- 對(duì)象:一切事物都可以是對(duì)象,更準(zhǔn)確的說(shuō),對(duì)象是一個(gè)實(shí)體,用一組可識(shí)別的特征和行為來(lái)標(biāo)識(shí),可以說(shuō)對(duì)象不同的地方就是具有不同的特征與行為。
- 類(lèi):是具有相同屬性和功能的對(duì)象抽象集合
實(shí)例:就是創(chuàng)建具體對(duì)象的過(guò)程
舉一個(gè)面向?qū)ο蟮睦樱何覀冃枰煲惠v車(chē),我們可能并不需要知道車(chē)的原理,我們只需要找到車(chē)的輪子,車(chē)的車(chē)架,車(chē)的發(fā)動(dòng)機(jī),然后將它們拼裝在一起即可。
在前面我們已經(jīng)使用了一些內(nèi)建的類(lèi)來(lái)展示數(shù)據(jù)和控制結(jié)構(gòu)的例子。面向?qū)ο缶幊陶Z(yǔ)言最強(qiáng)大的一項(xiàng)特性是允許程序員(問(wèn)題求解者) 創(chuàng)建全新的類(lèi)來(lái)對(duì)求解問(wèn)題所需的數(shù)據(jù)進(jìn)行建模。
我們之前使用了抽象數(shù)據(jù)類(lèi)型來(lái)對(duì)數(shù)據(jù)對(duì)象的狀態(tài)及行為進(jìn)行邏輯描述。通過(guò)構(gòu)建能實(shí)現(xiàn)抽象數(shù)據(jù)類(lèi)型的類(lèi),可以利用抽象過(guò)程,同時(shí)為真正在程序中運(yùn)用抽象提供必要的細(xì)節(jié)。每當(dāng)需要實(shí)現(xiàn)抽象數(shù)據(jù)類(lèi)型時(shí),就可以創(chuàng)建新類(lèi)。
2. 構(gòu)建類(lèi)
我們來(lái)構(gòu)建一個(gè)分?jǐn)?shù)類(lèi)fraction類(lèi):

你這不能用除法?其實(shí)是可以,但是除法的方式python已經(jīng)有自己的類(lèi)了,我這里需要自己創(chuàng)建一個(gè)分?jǐn)?shù)類(lèi)。
所有類(lèi)都應(yīng)該首先提供構(gòu)造方法。構(gòu)造方法定義了數(shù)據(jù)對(duì)象的創(chuàng)建方式。要?jiǎng)?chuàng)建 Fraction 類(lèi)的實(shí)例,必須調(diào)用構(gòu)造方法,要?jiǎng)?chuàng)建一個(gè) Fraction 對(duì)象,需要提供分子和分母兩部分?jǐn)?shù)據(jù)。
class fraction: #定義一個(gè)類(lèi)
def __init__(self,top,bottom):#定義構(gòu)造方法 __init__
self.num=top
self.den=bottom
這里解釋一下,self 是一個(gè)總是指向?qū)ο蟊旧淼奶厥鈪?shù),它必須是第一 個(gè)形式參數(shù)。然而,在調(diào)用方法時(shí),從來(lái)不需要提供相應(yīng)的實(shí)際參數(shù)。如前所述,分?jǐn)?shù)需要分子與分母兩部分狀態(tài)數(shù)據(jù)。構(gòu)造方法中的 self.num 定義了 Fraction 對(duì)象有一個(gè)叫作 num 的內(nèi)部數(shù)據(jù)對(duì)象作為其狀態(tài)的一部分。同理,self.den 定義了分母。這兩個(gè)實(shí)際參數(shù)的值在初始時(shí),賦給了狀態(tài),使得新創(chuàng)建的 Fraction 對(duì)象能夠知道其初始值。
class fraction: #定義一個(gè)類(lèi)
def __init__(self,top,bottom):#定義構(gòu)造方法 __init__
self.num=top
self.den=bottom
myfraction = fraction(3,5)#使用類(lèi)創(chuàng)建一個(gè)對(duì)象。
我們可以用下面這個(gè)圖來(lái)描述,我們構(gòu)造類(lèi)一個(gè)類(lèi),然后通過(guò)類(lèi)創(chuàng)建了一個(gè)對(duì)象。

一般情況下,我們定義了一個(gè)類(lèi),里面會(huì)有這個(gè)類(lèi)的一些方法,例如,我要查看這個(gè)分?jǐn)?shù)對(duì)象的樣子,我要計(jì)算這中類(lèi)型的分?jǐn)?shù),等等方法,這些都需要我們?nèi)ザx。
class fraction: #定義一個(gè)類(lèi)
def __init__(self,top,bottom):#定義構(gòu)造方法 __init__
self.num=top
self.den=bottom
def show(self): #定義輸出方法
print(self.num,"/",self.den)
def add(self,otherf): #定義分?jǐn)?shù)加法
bot=otherf.den * self.den
top=self.num * otherf.den +self.den * otherf.num
print(top,"/",bot)
#定義兩個(gè)分?jǐn)?shù)
myfraction=fraction(9,16)
a=fraction(1,16)
#試試加法
myfraction.add(a)
結(jié)果如下:

這里我們放上我們寫(xiě)好的分?jǐn)?shù)類(lèi)定義方法。
class Fraction:
def __init__(self, top, bottom):
self.num = top
self.den = bottom
def __str__(self):
return str(self.num) + "/" + str(self.den)
def show(self):
print(self.num, "/", self.den)
def __add__(self, otherfraction): #加法 ,可以用+
newnum = self.num * otherfraction.den + self.den * otherfraction.num
newden = self.den * otherfraction.den
common = gcd(newnum, newden)
return Fraction(newnum//common, newden//common)
def __eq__(self, other): #深相等,值相等就相等
firstnum = self.num * other.den
secondnum = other.num * self.den
return firstnum == secondnum
3. 繼承
繼承是面向?qū)ο缶幊痰囊粋€(gè)重要特征:使一個(gè)類(lèi)與另一個(gè)類(lèi)相關(guān)聯(lián),就像人們相互聯(lián)系一樣。孩子從父母那里繼承了特征,python的子類(lèi)可以從父類(lèi)那繼承數(shù)據(jù)和行為,父類(lèi)也稱(chēng)為超類(lèi)。
就拿我們前面學(xué)習(xí)過(guò)的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)舉例。

列表、字符串和元組都是有序集合。它們都繼承了共同的數(shù)據(jù)組織和操作。不過(guò),根據(jù)數(shù)據(jù)是否同類(lèi)以及集合是否可修改,它們彼此又有區(qū)別。子類(lèi)從父類(lèi)繼承共同的特征,但是通過(guò)額外的特征彼此區(qū)分。
3.1 繼承案例
我們這里通過(guò)一個(gè)小的案例來(lái)實(shí)現(xiàn)繼承的案例,我們來(lái)構(gòu)建一個(gè)模擬程序,用于模擬數(shù)字電路。邏輯門(mén)是這個(gè)模擬程序的基本構(gòu)造單元,它們代表其輸入和輸出之間的布爾代數(shù)關(guān)系。

通過(guò)不同的模式將這些邏輯門(mén)組合起來(lái)并提供一系列輸入值,可以構(gòu)建具有邏輯功能的電 路。圖 1-10 展示了一個(gè)包含兩個(gè)與門(mén)、一個(gè)或門(mén)和一個(gè)非門(mén)的電路。兩個(gè)與門(mén)的輸出直接作為 輸入傳給或門(mén),然后其輸出又輸入給非門(mén)。如果在 4 個(gè)輸入處(每個(gè)與門(mén)有兩個(gè)輸入)提供一系列值,那么非門(mén)就會(huì)輸出結(jié)果。

為了實(shí)現(xiàn)電路,首先需要構(gòu)建邏輯門(mén)的表示??梢暂p松地將邏輯門(mén)組織成類(lèi)的繼承層次結(jié)構(gòu), 如圖所示。頂部的 LogicGate 類(lèi)代表邏輯門(mén)的通用特性:邏輯門(mén)的標(biāo)簽和一個(gè)輸出。下面 一層子類(lèi)將邏輯門(mén)分成兩種:有一個(gè)輸入的邏輯門(mén)和有兩個(gè)輸入的邏輯門(mén)。再往下,就是具體的邏輯門(mén)。

首先定義父類(lèi)LogicGate
class LogicGate:
def __init__(self, n):#構(gòu)造函數(shù),label代表的是自己的名字
self.label = n
self.output = None
def getLabel(self):#輸出名字的函數(shù)
return self.label
def getOutput(self):#輸出的結(jié)果
self.output = self.performGateLogic()
return self.output
目前還不用實(shí)現(xiàn) performGateLogic 函數(shù)。原因在于,我們不知道每一種邏輯門(mén)將如何進(jìn) 行自己的邏輯運(yùn)算。這些細(xì)節(jié)會(huì)交由繼承層次結(jié)構(gòu)中的每一個(gè)邏輯門(mén)來(lái)實(shí)現(xiàn)。這是一種在面向?qū)ο缶幊讨蟹浅?qiáng)大的思想——我們創(chuàng)建了一個(gè)方法,而其代碼還不存在。參數(shù) self 是指向?qū)嶋H調(diào)用方法的邏輯門(mén)對(duì)象的引用。任何添加到繼承層次結(jié)構(gòu)中的新邏輯門(mén)都僅需要實(shí)現(xiàn)之后會(huì)被調(diào)用的 performGateLogic 函數(shù)。一旦實(shí)現(xiàn)完成,邏輯門(mén)就可以提供運(yùn)算結(jié)果。擴(kuò)展已有的繼承層次結(jié)構(gòu)并提供使用新類(lèi)所需的特定函數(shù),這種能力對(duì)于重用代碼來(lái)說(shuō)非常重要。
定義子類(lèi)BinaryGate類(lèi)、UnaryGate類(lèi)
兩個(gè)類(lèi)中的構(gòu)造方法首先使用 super 函數(shù) 來(lái)調(diào)用其父類(lèi)的構(gòu)造方法。當(dāng)創(chuàng)建 BinaryGate 類(lèi)的實(shí)例時(shí),首先要初始化所有從LogicGate 中繼承來(lái)的數(shù)據(jù)項(xiàng),在這里就是邏輯門(mén)的標(biāo)簽。接著,構(gòu)造方法添加兩個(gè)輸入(pinA 和 pinB)。 這是在構(gòu)建類(lèi)繼承層次結(jié)構(gòu)時(shí)常用的模式。子類(lèi)的構(gòu)造方法需要先調(diào)用父類(lèi)的構(gòu)造方法,然后再 初始化自己獨(dú)有的數(shù)據(jù)。
BinaryGate類(lèi)主要是與門(mén)和或門(mén)(有兩個(gè)輸入)
class BinaryGate(LogicGate):
def __init__(self, n):
super().__init__(n)#繼承父類(lèi)的構(gòu)造方法
self.pinA = None #添加自己的參數(shù)
self.pinB = None
def getPinA(self):#自己的方法
return int(input("Enter Pin A input for gate "+self.getLabel() + "-->"))
def getPinB(self):#自己的方法
return int(input("Enter Pin B input for gate "+self.getLabel() + "-->"))
UnaryGate類(lèi)主要是非門(mén)(只有一個(gè)輸入)。
class UnaryGate(LogicGate):
def __init__(self, n):
super().__init__(n)#繼承父類(lèi)的構(gòu)造方法
self.pin = None#添加自己的參數(shù)
def getPin(self):#自己的方法
return int(input("Enter Pin input for gate " + self.getLabel() + "-->"))
構(gòu)造孫類(lèi)(與門(mén)、或門(mén)、非門(mén))
與門(mén) AndGate類(lèi)
#構(gòu)造與門(mén)
class AndGate(BinaryGate):
def __init__(self, n):
super().__init__(n)#繼承父類(lèi)方法
def performGateLogic(self):#自己的運(yùn)算邏輯
a = self.getPinA()
b = self.getPinB()
if a==1 and b==1:
return 1
else:
return 0
或門(mén) OrGate
class OrGate(BinaryGate):
def __init__(self, n):
super().__init__(n)#繼承父類(lèi)方法
def performGateLogic(self):
a = self.getPinA()
b = self.getPinB()
if a==1 or b==1:
return 1
else:
return 0
非門(mén) NotGate
class NotGate(UnaryGate):
def __init__(self, n):
super().__init__(n)
def performGateLogic(self):
a = self.getPin()
if a==1:
return 0
else:
return 1
測(cè)試一下結(jié)果:
與門(mén)

或門(mén)

非門(mén)

參考資料:
- 《python數(shù)據(jù)結(jié)構(gòu)與算法》
- 《大話(huà)數(shù)據(jù)結(jié)構(gòu)》
到此這篇關(guān)于python數(shù)據(jù)結(jié)構(gòu)之面向?qū)ο蟮奈恼戮徒榻B到這了,更多相關(guān)python面向?qū)ο髢?nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Python實(shí)現(xiàn)字典合并的四種方法
這篇文章主要為大家詳細(xì)介紹了Python的合并字典的四種方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-03-03
Python?PaddleNLP開(kāi)源實(shí)現(xiàn)快遞單信息抽取
這篇文章主要為大家介紹了Python?PaddleNLP開(kāi)源項(xiàng)目實(shí)現(xiàn)對(duì)快遞單信息抽取,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
python實(shí)現(xiàn)按行切分文本文件的方法
這篇文章主要介紹了python實(shí)現(xiàn)按行切分文本文件的方法,涉及Python利用shell命令操作文本文件的相關(guān)技巧,需要的朋友可以參考下2016-04-04
python [::-1] [::-1,::-1]的具體使用
本文主要介紹了python [::-1] [::-1,::-1]的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05
利用pyecharts實(shí)現(xiàn)地圖可視化的例子
今天小編就為大家分享一篇利用pyecharts實(shí)現(xiàn)地圖可視化的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-08-08
Python Sympy計(jì)算梯度、散度和旋度的實(shí)例
今天小編就為大家分享一篇Python Sympy計(jì)算梯度、散度和旋度的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-12-12
Django import export實(shí)現(xiàn)數(shù)據(jù)庫(kù)導(dǎo)入導(dǎo)出方式
這篇文章主要介紹了Django import export實(shí)現(xiàn)數(shù)據(jù)庫(kù)導(dǎo)入導(dǎo)出方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04
request基本使用及各種請(qǐng)求方式參數(shù)的示例
這篇文章主要為大家介紹了request的基本使用及各種請(qǐng)求方式參數(shù)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04

