W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
你想實現(xiàn)一個自定義的類來模擬內(nèi)置的容器類功能,比如列表和字典。但是你不確定到底要實現(xiàn)哪些方法。
collections
定義了很多抽象基類,當(dāng)你想自定義容器類的時候它們會非常有用。比如你想讓你的類支持迭代,那就讓你的類繼承 collections.Iterable
即可:
import collections
class A(collections.Iterable):
pass
不過你需要實現(xiàn) collections.Iterable
所有的抽象方法,否則會報錯:
>>> a = A()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class A with abstract methods __iter__
>>>
你只要實現(xiàn) __iter__()
方法就不會報錯了(參考4.2和4.7小節(jié))。
你可以先試著去實例化一個對象,在錯誤提示中可以找到需要實現(xiàn)哪些方法:
>>> import collections
>>> collections.Sequence()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Sequence with abstract methods \
__getitem__, __len__
>>>
下面是一個簡單扼示例,繼承自上面Sequence抽象類,并且實現(xiàn)元素按照順序存儲:
class SortedItems(collections.Sequence):
def __init__(self, initial=None):
self._items = sorted(initial) if initial is not None else []
# Required sequence methods
def __getitem__(self, index):
return self._items[index]
def __len__(self):
return len(self._items)
# Method for adding an item in the right location
def add(self, item):
bisect.insort(self._items, item)
items = SortedItems([5, 1, 3])
print(list(items))
print(items[0], items[-1])
items.add(2)
print(list(items))
可以看到,SortedItems跟普通的序列沒什么兩樣,支持所有常用操作,包括索引、迭代、包含判斷,甚至是切片操作。
這里面使用到了 bisect
模塊,它是一個在排序列表中插入元素的高效方式。可以保證元素插入后還保持順序。
使用 collections
中的抽象基類可以確保你自定義的容器實現(xiàn)了所有必要的方法。并且還能簡化類型檢查。你的自定義容器會滿足大部分類型檢查需要,如下所示:
>>> items = SortedItems()
>>> import collections
>>> isinstance(items, collections.Iterable)
True
>>> isinstance(items, collections.Sequence)
True
>>> isinstance(items, collections.Container)
True
>>> isinstance(items, collections.Sized)
True
>>> isinstance(items, collections.Mapping)
False
>>>
collections
中很多抽象類會為一些常見容器操作提供默認的實現(xiàn),這樣一來你只需要實現(xiàn)那些你最感興趣的方法即可。假設(shè)你的類繼承自 collections.MutableSequence
,如下:
class Items(collections.MutableSequence):
def __init__(self, initial=None):
self._items = list(initial) if initial is not None else []
# Required sequence methods
def __getitem__(self, index):
print('Getting:', index)
return self._items[index]
def __setitem__(self, index, value):
print('Setting:', index, value)
self._items[index] = value
def __delitem__(self, index):
print('Deleting:', index)
del self._items[index]
def insert(self, index, value):
print('Inserting:', index, value)
self._items.insert(index, value)
def __len__(self):
print('Len')
return len(self._items)
如果你創(chuàng)建 Items
的實例,你會發(fā)現(xiàn)它支持幾乎所有的核心列表方法(如append()、remove()、count()等)。下面是使用演示:
>>> a = Items([1, 2, 3])
>>> len(a)
Len
3
>>> a.append(4)
Len
Inserting: 3 4
>>> a.append(2)
Len
Inserting: 4 2
>>> a.count(2)
Getting: 0
Getting: 1
Getting: 2
Getting: 3
Getting: 4
Getting: 5
2
>>> a.remove(3)
Getting: 0
Getting: 1
Getting: 2
Deleting: 2
>>>
本小節(jié)只是對Python抽象類功能的拋磚引玉。numbers
模塊提供了一個類似的跟整數(shù)類型相關(guān)的抽象類型集合。可以參考8.12小節(jié)來構(gòu)造更多自定義抽象基類。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: