28. 自定義容器類型需要繼承自COLLECTIONS.ABC

Python中需要經常自定義各種類來包含數據,在類中描述對象之間的關係。每一個類都會封裝屬性和方法。同時Python還提供了各種內嵌的容器,例如:list, tuple。

當你用類來表示一些簡單應用時,例如表示一個序列,通常你會選擇定義一個list的子類。例如定義一個列表,這個列表包含一個額外的方法來記錄成員出現的頻率。

28. 自定義容器類型需要繼承自COLLECTIONS.ABC

通過繼承自list類,這個新類包含了list所有的全部方法,這使得任何Python程序員都能很快上手使用這個新類。而這個類額外提供的方法又使得類有了更多的功能。

28. 自定義容器類型需要繼承自COLLECTIONS.ABC

想象一下,有一個類,它不是list的子類,但是又有list的功能。例如給一個二叉樹類提供序列的語法(例如:list或者tuple)。

28. 自定義容器類型需要繼承自COLLECTIONS.ABC

怎麼樣才能把二叉樹變得像序列一樣呢?Python使用具有特殊名稱的實例方法實現其容器行為。例如通過下標訪問列表元素的方法如下:

28. 自定義容器類型需要繼承自COLLECTIONS.ABC

其實Python解釋器在後臺是這樣實現的:

28. 自定義容器類型需要繼承自COLLECTIONS.ABC

為了使二叉樹類能夠像序列一樣工作,你可以給二叉樹實例化一個__getitem__方法,這個方法以深度優先的方式檢索二叉樹。

28. 自定義容器類型需要繼承自COLLECTIONS.ABC

接下來仍然按照以前的方式構造二叉樹:

28. 自定義容器類型需要繼承自COLLECTIONS.ABC

此時你就可以像訪問列表一樣訪問二叉樹了:

28. 自定義容器類型需要繼承自COLLECTIONS.ABC

雖然上面實現了用下標的方式訪問二叉樹,但是相對於列表來說還有很多方法沒有實現,了例如:

28. 自定義容器類型需要繼承自COLLECTIONS.ABC

這是因為len()方法要求被調用對象需要實現一個__len__方法:

28. 自定義容器類型需要繼承自COLLECTIONS.ABC

如果像這樣給每個列表方法都重寫一遍就太麻煩了。此時可以使用collections.abc模塊,這個模塊定義了一些列通用的抽象基類,這些基類提供了每一個容器類型的典型方法。當你的類繼承自這些抽象基類時,如果忘記重寫某些方法了,編譯時就會出錯並指出那些必要方法沒有重寫。

28. 自定義容器類型需要繼承自COLLECTIONS.ABC

一旦你重寫了序列的全部必要方法,那麼你的新類就可以按照序列使用了。

28. 自定義容器類型需要繼承自COLLECTIONS.ABC

28. 自定義容器類型需要繼承自COLLECTIONS.ABC


分享到:


相關文章: