導語:本文章記錄了本人在學習Python基礎之面向對象篇的重點知識及我的心得,打算入門Python的朋友們能夠來一塊兒學習並交流。
本文重點:安全
一、協議是Python中非正式的接口;
二、瞭解抽象基類的基本概念以及標準庫中的抽象基類;
三、掌握抽象基類的使用方法。
協議:是Python中非正式的接口,是令Python這種動態類型語言實現多態的方式。
接口:泛指實體把本身提供給外界的一種抽象化物(能夠爲另外一實體),用以由內部操做分離出外部溝通方法,使其能被內部修改而不影響外界其餘實體與其交互的方式。
類的接口:類實現或繼承的公開屬性(方法或數據屬性),包括特殊方法,如__getitem__或__add__。app
協議是非正式的,只由文檔和約定定義,不具有強制性。
以序列協議爲例,假設咱們想實現迭代以及in運算,一般須要__iter__和__contains__方法,但事實上只實現__getitem__方法也能夠。緣由在於當Python發現沒有__iter__和__contains__可用時,會轉而調用__getitem__方法設法讓迭代和in運算符可用。
小結:部分實現協議是有用的。ssh
在運行時修改類或模塊而不改動源碼,從而實現目標協議接口的操做就是打猴子補丁。函數
鴨子類型(duck typing):不關注對象的類型,而是關注對象具備的行爲(方法)。
鴨子類型像多態同樣工做,可是沒有繼承。
在鴨子類型中,協議風格的接口與繼承徹底沒有關係,實現同一個協議的各個類是相互獨立的。學習
白鵝類型(goose typing):只要cls是抽象基類,即cls的元類是abc.ABCMeta,就可使用isinstance(obj,cls)。spa
抽象基類(abstract base class,ABC):抽象基類就是類裏定義了純虛成員函數的類。純虛函數只提供了接口,並無具體實現。抽象基類不能被實例化(不能建立對象),一般是做爲基類供子類繼承,子類中重寫虛函數,實現具體的接口。
簡言之,ABC描述的是至少使用一個純虛函數的接口,從ABC派生出的類將根據派生類的具體特徵,使用常規虛函數來實現這種接口。code
(1)collections.abc中抽象基類
collections.abc模塊中各個抽象基類的UML類圖以下所示:
對象
Iterable 經過 __iter__ 方法支持迭代;
Container 經過__contains__ 方法支持 in 運算符;
Sized 經過 __len__ 方法支持len() 函數。
(2)numbers包中的數字塔
按照自上而下的線性結構,Number是位於最頂端的超類,詳細排序以下:排序
例如,檢查一個數是不是整數,可使用isinstance(x,numbers.Integral)。繼承
聲明抽象基類最簡單的方式是繼承abc.ABC或其餘抽象基類:Class Student(abc.ABC)
注意:在Python3.0~3.3之間,繼承抽象基類的語法是:Class Student(metaclass=abc.ABCMeta)。
在定義抽象基類的子類時,子類須要將繼承的抽象基類中的抽象方法具體實現。
虛擬子類:指的是不經過繼承而利用註冊把一個類變成抽象基類的子類。
註冊虛擬之類的方式是調用register方法,語法是@抽象基類名稱.register。經註冊後的虛擬子類能夠被issubclass和isinstance等函數識別,可是註冊的類不會從抽象基類中繼承任何方法或屬性。具體可經過類屬性__mro__查看類的真實繼承關係。
一、抽象基類中聲明抽象類方法須要使用@abc.abstractmethod標記,而且在@abc.abstractmethod和def之間不能有其餘裝飾器。二、內省類的繼承關係的方法:__subclasses__():返回類的直接子類列表,不含虛擬子類。__abcregistry:抽象基類獨有的屬性,是抽象類註冊的虛擬子類的弱引用。三、__subclasshook__:令抽象基類識別沒有進行子類化和註冊的類,此方法在abc.Sized中有應用。