#古典類在python2.x中運行 class A: pass print(dir(A)) # ['__doc__', '__module__'] print(A.__bases__) # () a = A() print(a.__class__) # __main__.A print(type(a)) # type 'instance'>
新式類
#新式類在python3.x中運行 class B: pass print(dir(B)) # ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] print(B.__bases__) # (class 'object'>,) B = B() print(B.__class__) # class '__main__.B'> print(type(B)) # class '__main__.B'>
OCP原則:多用”繼承“,少修改
繼承的用途:增強基類,實現(xiàn)多態(tài)
多態(tài)
多繼承很好的模擬了世界,因為事務(wù)很少單一繼承,但是舍棄簡單,必然引入復(fù)雜性,帶來了沖突
如同一個孩子繼承了來自父母雙方的特征,那么到底眼睛像爸爸還是媽媽尼?孩子究竟改像誰多一點尼?
多繼承的實現(xiàn)會導(dǎo)致編譯器設(shè)計的復(fù)雜度增加,所以現(xiàn)在很多語言舍棄了類的多繼承
C++支持多繼承;Java舍棄了多繼承
多繼承可能會帶來二義性,例如,貓和狗都繼承自動物類,現(xiàn)在一個類多繼承了貓和狗類,貓和狗都有了shout方法,子類究竟繼承誰的shout尼?
class ClassName(基類列表): 類體
多繼承帶來的路徑選擇問題,究竟繼承那個父類的特征尼?
Python使用MRO(method resolution order) 解決類搜索順序問題。
當(dāng)類很多,繼承復(fù)雜的情況下,繼承路徑太多,很難說清什么樣的繼承路徑
團隊協(xié)作開發(fā),如果引入多繼承,那代碼將不可控
不管編程語言是否支持多繼承,都應(yīng)當(dāng)避免多繼承
Pythond的面向?qū)ο?,我們看到太靈活,太開放,所以要團隊守規(guī)矩
類有下面的繼承關(guān)系
文檔Document類是其他所有文檔類的抽象基類,Word、Pdf類是Document的子類
需求:為Document子類提供打印能力思路:
1、在Document中提供print方法
class Document: def __init__(self,content): self.coutent = content def print(self): print(self.coutent) class Word(Document): pass class Pdf(Document): pass a = Word("tom com") a.print() # tom com
基類提供的方法不因該具體實現(xiàn),因為它未必適合子類的打印,子類中需要覆蓋重寫。
print算是一種能力 -- 打印功能,不是所有的Document的子類都需要的,所以,從這個角度出發(fā)有點問題
class Document: def __init__(self,content): self.coutent = content def print(self): print(self.coutent) class Word(Document): def print(self): print("Word print {}".format(self.coutent)) class Pdf(Document): pass a = Word("tom com") a.print() # Word print tom com
思路二:需要打印的子類上增加
如果現(xiàn)有子類上直接增加,違反了OCP的原則,所以應(yīng)該繼承后增加
class Document: # 不允許修改 def __init__(self,content): self.coutent = content def print(self): print(self.coutent) class Word(Document): pass # 不允許修改 class Pdf(Document): pass # 不允許修改 class PrinttableWord(Word): def print(self): print("PrinttableWord print {}".format(self.coutent)) print(PrinttableWord.mro()) # [class '__main__.PrinttableWord'>, class '__main__.Word'>, class '__main__.Document'>, class 'object'>] a = PrinttableWord("tom com") a.print() # PrinttableWord print tom com
看似不錯,如果還要提供其他類似能力,如何繼承?
應(yīng)用于網(wǎng)絡(luò),文檔應(yīng)該具備序列化的能力,類上就應(yīng)該實現(xiàn)序列化可序列化還可能分為使用pickle、josn、messagepack等
這個時候,發(fā)現(xiàn),類又可能太多了,繼承的方式不是很好了
功能太多,A類需要某幾樣功能,B類需要另外幾樣功能,很繁瑣
思路三:裝飾器,用裝飾器增強一個類,把功能給類附加上去,那個類需要,就裝飾它
def printable(cls): def _print(self): print("_print 裝飾器 {}".format(self.coutent)) return _print cls.print = _print return cls class Document: def __init__(self,content): self.coutent = content def print(self): print(self.coutent) class Word(Document): pass class Pdf(Document): pass @printable class PrinttableWord(Word): pass #先繼承,后裝飾 print(PrinttableWord.__dict__) # {'__module__': '__main__', '__doc__': None, 'print': function printable.locals>._print at 0x0173C228>} a = PrinttableWord("tom") a.print() # _print 裝飾器 tom
優(yōu)點:簡單方便,在需要的地方動態(tài)增加
思路四:Mixin 【用類去繼承】
先看代碼
class PrintableMixin: def print(self): print("PrintableMixin {}".format(self.coutent)) class Document: def __init__(self,content): self.coutent = content def print(self): print(self.coutent) class Word(Document): pass class Pdf(Document): pass class PrinttableWord(PrintableMixin,Word): pass print(PrinttableWord.mro()) # [class '__main__.PrinttableWord'>, class '__main__.PrintableMixin'>, class '__main__.Word'>, class '__main__.Document'>, class 'object'>] print(PrinttableWord.__dict__) # {'__module__': '__main__', '__doc__': None} a = PrinttableWord("tom") a.print() # PrintableMixin tom
Mixin就是其他類混合進來,同時帶來了類的屬性和方法
這里看來Mixin類和裝飾器效果一樣,也什么特別的,但是Mixin是類,就可以繼承,增強功能
class PrintableMixin: def print(self): print("PrintableMixin {}".format(self.coutent)) class Document: def __init__(self,content): self.coutent = content def print(self): print(self.coutent) class Word(Document): pass class Pdf(Document): pass class PrinttableWord(PrintableMixin,Word): pass class SuperPrintableMixin(PrintableMixin,Word): def print(self): print("~"*30) super(SuperPrintableMixin, self).print() print("~"*30) print(SuperPrintableMixin.mro()) # [class '__main__.SuperPrintableMixin'>, class '__main__.PrintableMixin'>, class '__main__.Word'>, class '__main__.Document'>, class 'object'>] print(SuperPrintableMixin.__dict__) # {'__module__': '__main__', 'print': function SuperPrintableMixin.print at 0x018264B0>, '__doc__': None} a = SuperPrintableMixin("tom") a.print() # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # PrintableMixin tom # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Minxin本質(zhì)上就是多繼承實現(xiàn)的
Mixin體現(xiàn)的是一種組合的設(shè)計模式
在面向?qū)ο蟮脑O(shè)計中,一個負載的類,往往需要很多功能,而這些功能有來自不同的類提供,這就需要很多的類組合在一起
從設(shè)計模式的角度來說,多組合,少繼承。
到此這篇關(guān)于總結(jié)Python類的多繼承知識的文章就介紹到這了,更多相關(guān)Python類的多繼承內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
標(biāo)簽:黔西 常德 四川 益陽 上海 惠州 黑龍江 鷹潭
巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《詳細總結(jié)Python類的多繼承知識》,本文關(guān)鍵詞 詳細,總結(jié),Python,類,的,多,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。