摘要:本文重點(diǎn)協(xié)議是中非正式的接口了解抽象基類的基本概念以及標(biāo)準(zhǔn)庫中的抽象基類掌握抽象基類的使用方法。三抽象基類的使用通過繼承聲明抽象基類聲明抽象基類最簡單的方式是繼承或其他抽象基類注意在之間,繼承抽象基類的語法是。
導(dǎo)語:本文章記錄了本人在學(xué)習(xí)Python基礎(chǔ)之面向?qū)ο笃闹攸c(diǎn)知識(shí)及個(gè)人心得,打算入門Python的朋友們可以來一起學(xué)習(xí)并交流。
本文重點(diǎn):
1、協(xié)議是Python中非正式的接口;一、協(xié)議的高度動(dòng)態(tài)本性 1、協(xié)議與接口的基本概念
2、了解抽象基類的基本概念以及標(biāo)準(zhǔn)庫中的抽象基類;
3、掌握抽象基類的使用方法。
協(xié)議:是Python中非正式的接口,是令Python這種動(dòng)態(tài)類型語言實(shí)現(xiàn)多態(tài)的方式。
接口:泛指實(shí)體把自己提供給外界的一種抽象化物(可以為另一實(shí)體),用以由內(nèi)部操作分離出外部溝通方法,使其能被內(nèi)部修改而不影響外界其他實(shí)體與其交互的方式。
類的接口:類實(shí)現(xiàn)或繼承的公開屬性(方法或數(shù)據(jù)屬性),包括特殊方法,如__getitem__或__add__。
協(xié)議是非正式的,只由文檔和約定定義,不具備強(qiáng)制性。
以序列協(xié)議為例,假設(shè)我們想實(shí)現(xiàn)迭代以及in運(yùn)算,通常需要__iter__和__contains__方法,但事實(shí)上只實(shí)現(xiàn)__getitem__方法也可以。原因在于當(dāng)Python發(fā)現(xiàn)沒有__iter__和__contains__可用時(shí),會(huì)轉(zhuǎn)而調(diào)用__getitem__方法設(shè)法讓迭代和in運(yùn)算符可用。
小結(jié):部分實(shí)現(xiàn)協(xié)議是有用的。
在運(yùn)行時(shí)修改類或模塊而不改動(dòng)源碼,從而實(shí)現(xiàn)目標(biāo)協(xié)議接口的操作就是打猴子補(bǔ)丁。
二、抽象基類 1、基本概念鴨子類型(duck typing):不關(guān)注對(duì)象的類型,而是關(guān)注對(duì)象具有的行為(方法)。鴨子類型像多態(tài)一樣工作,但是沒有繼承。
在鴨子類型中,協(xié)議風(fēng)格的接口與繼承完全沒有關(guān)系,實(shí)現(xiàn)同一個(gè)協(xié)議的各個(gè)類是相互獨(dú)立的。
白鵝類型(goose typing):只要cls是抽象基類,即cls的元類是abc.ABCMeta,就可以使用isinstance(obj,cls)。
抽象基類(abstract base class,ABC):抽象基類就是類里定義了純虛成員函數(shù)的類。純虛函數(shù)只提供了接口,并沒有具體實(shí)現(xiàn)。抽象基類不能被實(shí)例化(不能創(chuàng)建對(duì)象),通常是作為基類供子類繼承,子類中重寫虛函數(shù),實(shí)現(xiàn)具體的接口。簡言之,ABC描述的是至少使用一個(gè)純虛函數(shù)的接口,從ABC派生出的類將根據(jù)派生類的具體特征,使用常規(guī)虛函數(shù)來實(shí)現(xiàn)這種接口。
2、標(biāo)準(zhǔn)庫中的抽象基類(1)collections.abc中抽象基類
collections.abc模塊中各個(gè)抽象基類的UML類圖如下所示:
Iterable、 Container 和 Sized
各個(gè)集合應(yīng)該繼承這三個(gè)抽象基類, 或者至少實(shí)現(xiàn)兼容的協(xié)議。
Iterable 通過 __iter__ 方法支持迭代;
Container 通過__contains__ 方法支持 in 運(yùn)算符;
Sized 通過 __len__ 方法支持len() 函數(shù)。
Sequence、 Mapping 和 Set
這三個(gè)是主要的不可變集合類型, 而且各自都有可變的子類。
MappingView
在 Python 3 中, 映射方法 .items()、 .keys() 和 .values() 返回的對(duì)象分別是 ItemsView、 KeysView 和 ValuesView 的實(shí)例。 前兩個(gè)類還從 Set 類繼承了豐富的接口,涉及集合的全部運(yùn)算符。
Callable 和 Hashable
這兩個(gè)抽象基類與集合沒有太大的關(guān)系,只不過因?yàn)閏ollections.abc 是標(biāo)準(zhǔn)庫中定義抽象基類的第一個(gè)模塊, 而它們又太重要了,因此才把它們放到 collections.abc 模塊中。Callable 或 Hashable 的子類非常少見。這兩個(gè)抽象基類的主要作用是為內(nèi)置函數(shù) isinstance 提供支持,以一種安全的方式判斷對(duì)象能不能調(diào)用或散列。
Iterator
是 Iterable 的子類。
(2)numbers包中的數(shù)字塔
按照自上而下的線性結(jié)構(gòu),Number是位于最頂端的超類,詳細(xì)排序如下:
Number
Complex
Real
Rational
Integral
例如,檢查一個(gè)數(shù)是否是整數(shù),可以使用isinstance(x,numbers.Integral)。
三、抽象基類的使用 1、通過繼承聲明抽象基類聲明抽象基類最簡單的方式是繼承abc.ABC或其他抽象基類:Class Student(abc.ABC)
注意:在Python3.0~3.3之間,繼承抽象基類的語法是:Class Student(metaclass=abc.ABCMeta)。
在定義抽象基類的子類時(shí),子類需要將繼承的抽象基類中的抽象方法具體實(shí)現(xiàn)。
3、聲明虛擬子類實(shí)現(xiàn)抽象基類的接口虛擬子類:指的是不通過繼承而利用注冊把一個(gè)類變成抽象基類的子類。
注冊虛擬之類的方式是調(diào)用register方法,語法是@抽象基類名稱.register。
經(jīng)注冊后的虛擬子類可以被issubclass和isinstance等函數(shù)識(shí)別,但是注冊的類不會(huì)從抽象基類中繼承任何方法或?qū)傩?。具體可通過類屬性__mro__查看類的真實(shí)繼承關(guān)系。
1、抽象基類中聲明抽象類方法需要使用@abc.abstractmethod標(biāo)記,并且在@abc.abstractmethod和def之間不能有其他裝飾器。
2、內(nèi)省類的繼承關(guān)系的方法:
__subclasses__():返回類的直接子類列表,不含虛擬子類。
__abcregistry:抽象基類獨(dú)有的屬性,是抽象類注冊的虛擬子類的弱引用。
3、__subclasshook__:令抽象基類識(shí)別沒有進(jìn)行子類化和注冊的類,此方法在abc.Sized中有應(yīng)用。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/41315.html
摘要:本篇內(nèi)容將從鴨子類型的動(dòng)態(tài)協(xié)議,逐漸過渡到使接口更明確能驗(yàn)證實(shí)現(xiàn)是否符合規(guī)定的抽象基類。抽象基類介紹完動(dòng)態(tài)實(shí)現(xiàn)接口后,現(xiàn)在開始討論抽象基類,它屬于靜態(tài)顯示地實(shí)現(xiàn)接口。標(biāo)準(zhǔn)庫中的抽象基類從開始,標(biāo)準(zhǔn)庫提供了抽象基類。 《流暢的Python》筆記。本篇是面向?qū)ο髴T用方法的第四篇,主要討論接口。本篇內(nèi)容將從鴨子類型的動(dòng)態(tài)協(xié)議,逐漸過渡到使接口更明確、能驗(yàn)證實(shí)現(xiàn)是否符合規(guī)定的抽象基類(Abst...
摘要:自己定義的抽象基類要繼承。抽象基類可以包含具體方法。這里想表達(dá)的觀點(diǎn)是我們可以偷懶,直接從抽象基類中繼承不是那么理想的具體方法。 抽象基類 抽象基類的常見用途: 實(shí)現(xiàn)接口時(shí)作為超類使用。 然后,說明抽象基類如何檢查具體子類是否符合接口定義,以及如何使用注冊機(jī)制聲明一個(gè)類實(shí)現(xiàn)了某個(gè)接口,而不進(jìn)行子類化操作。 如何讓抽象基類自動(dòng)識(shí)別任何符合接口的類——不進(jìn)行子類化或注冊。 接口在動(dòng)態(tài)類...
摘要:本文重點(diǎn)不要試圖在內(nèi)置類型的子類中重寫方法,可以繼承的可拓展類尋求變通掌握多重繼承中的和了解處理多重繼承的一些建議。子類化的代碼如下輸出小結(jié)上述問題只發(fā)生在語言實(shí)現(xiàn)的內(nèi)置類型子類化情況中,而且只影響直接繼承內(nèi)置類型的自定義類。 導(dǎo)語:本文章記錄了本人在學(xué)習(xí)Python基礎(chǔ)之面向?qū)ο笃闹攸c(diǎn)知識(shí)及個(gè)人心得,打算入門Python的朋友們可以來一起學(xué)習(xí)并交流。 本文重點(diǎn): 1、不要試圖在內(nèi)置...
摘要:于發(fā)表了著名的有害論的論文引起了長達(dá)數(shù)年的論戰(zhàn)并由此產(chǎn)生了結(jié)構(gòu)化程序設(shè)計(jì)方法。到現(xiàn)在為止面向?qū)ο笠呀?jīng)成為了主流的開發(fā)思想。面向?qū)ο蟮某绦蛟O(shè)計(jì)優(yōu)點(diǎn)解決了程序的擴(kuò)展性。 [Python3]Python面向?qū)ο蟮某绦蛟O(shè)計(jì) 一、面向?qū)ο蟮某绦蛟O(shè)計(jì)的由來 1.第一階段:面向機(jī)器,1940年以前 最早的程序設(shè)計(jì)都是采用機(jī)器語言來編寫的,直接使用二進(jìn)制碼來表示機(jī)器能夠識(shí)別和執(zhí)行的指令和數(shù)據(jù)。 簡單來...
摘要:本篇主要講述中使用函數(shù)來實(shí)現(xiàn)策略模式和命令模式,最后總結(jié)出這種做法背后的思想。 《流暢的Python》筆記。本篇主要講述Python中使用函數(shù)來實(shí)現(xiàn)策略模式和命令模式,最后總結(jié)出這種做法背后的思想。 1. 重構(gòu)策略模式 策略模式如果用面向?qū)ο蟮乃枷雭砗唵谓忉尩脑?,其?shí)就是多態(tài)。父類指向子類,根據(jù)子類對(duì)同一方法的不同重寫,得到不同結(jié)果。 1.1 經(jīng)典的策略模式 下圖是經(jīng)典的策略模式的U...
閱讀 2221·2021-10-12 10:11
閱讀 912·2021-10-09 09:41
閱讀 3897·2021-09-09 11:37
閱讀 2032·2021-09-08 10:41
閱讀 2698·2019-08-30 12:58
閱讀 2429·2019-08-30 10:58
閱讀 1356·2019-08-26 13:40
閱讀 4254·2019-08-26 13:36