collections.abc --- 容器的抽象基類?
3.3 新版功能: 該模塊曾是 collections 模塊的組成部分。
該模塊定義了一些 抽象基類,它們可用于判斷一個(gè)具體類是否具有某一特定的接口;例如,這個(gè)類是否可哈希,或其是否為映射類。
容器抽象基類?
這個(gè)容器模塊提供了以下 ABCs:
抽象基類 |
繼承自 |
抽象方法 |
Mixin 方法 |
|---|---|---|---|
|
|||
|
|||
|
|||
|
|
||
|
|||
|
|
||
|
|||
|
|||
|
|||
|
|
||
|
繼承自 |
||
|
繼承自 |
||
|
|
||
|
繼承自 |
||
|
|
||
|
繼承自 |
||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|
||
|
|||
|
|
||
|
|
-
class
collections.abc.Container? -
class
collections.abc.Hashable? -
class
collections.abc.Sized? -
class
collections.abc.Callable? 分別提供了
__contains__(),__hash__(),__len__()和__call__()方法的抽象基類。
-
class
collections.abc.Iterable? 提供了
__iter__()方法的抽象基類。使用
isinstance(obj, Iterable)可以檢測(cè)一個(gè)類是否已經(jīng)注冊(cè)到了Iterable或者實(shí)現(xiàn)了__iter__()函數(shù),但是無(wú)法檢測(cè)這個(gè)類是否能夠使用__getitem__()方法進(jìn)行迭代。檢測(cè)一個(gè)對(duì)象是否是 iterable 的唯一可信賴的方法是調(diào)用iter(obj)。
-
class
collections.abc.Collection? 集合了 Sized 和 Iterable 類的抽象基類。
3.6 新版功能.
-
class
collections.abc.Iterator? 提供了
__iter__()和__next__()方法的抽象基類。參見 iterator 的定義。
-
class
collections.abc.Reversible? 為可迭代類提供了
__reversed__()方法的抽象基類。3.6 新版功能.
-
class
collections.abc.Generator? 生成器類,實(shí)現(xiàn)了 PEP 342 中定義的協(xié)議,繼承并擴(kuò)展了迭代器,提供了
send(),throw()和close()方法。參見 generator 的定義。3.5 新版功能.
-
class
collections.abc.Sequence? -
class
collections.abc.MutableSequence? -
class
collections.abc.ByteString? 只讀且可變的序列 sequences 的抽象基類。
實(shí)現(xiàn)筆記:一些混入(Maxin)方法比如
__iter__(),__reversed__()和index()會(huì)重復(fù)調(diào)用底層的__getitem__()方法。因此,如果實(shí)現(xiàn)的__getitem__()是常數(shù)級(jí)訪問(wèn)速度,那么相應(yīng)的混入方法會(huì)有一個(gè)線性的表現(xiàn);然而,如果底層方法是線性實(shí)現(xiàn)(例如鏈表),那么混入方法將會(huì)是平方級(jí)的表現(xiàn),這也許就需要被重構(gòu)了。在 3.5 版更改: index() 方法支持 stop 和 start 參數(shù)。
-
class
collections.abc.MappingView? -
class
collections.abc.ItemsView? -
class
collections.abc.KeysView? -
class
collections.abc.ValuesView? 映射及其鍵和值的視圖 views 的抽象基類。
-
class
collections.abc.Awaitable? 為可等待對(duì)象 awaitable 提供的類,可以被用于
await表達(dá)式中。習(xí)慣上必須實(shí)現(xiàn)__await__()方法。協(xié)程對(duì)象 Coroutine 和
Coroutine抽象基類的實(shí)例都是這個(gè)抽象基類的實(shí)例。注解
在 CPython 里,基于生成器的協(xié)程(使用
types.coroutine()或asyncio.coroutine()包裝的生成器)都是 可等待對(duì)象,即使他們不含有__await__()方法。使用isinstance(gencoro, Awaitable)來(lái)檢測(cè)他們會(huì)返回False。要使用inspect.isawaitable()來(lái)檢測(cè)他們。3.5 新版功能.
-
class
collections.abc.Coroutine? 用于協(xié)程兼容類的抽象基類。實(shí)現(xiàn)了如下定義在 協(xié)程對(duì)象: 里的方法:
send(),throw()和close()。通常的實(shí)現(xiàn)里還需要實(shí)現(xiàn)__await__()方法。所有的Coroutine實(shí)例都必須是Awaitable實(shí)例。參見 coroutine 的定義。注解
在 CPython 里,基于生成器的協(xié)程(使用
types.coroutine()或asyncio.coroutine()包裝的生成器)都是 可等待對(duì)象,即使他們不含有__await__()方法。使用isinstance(gencoro, Coroutine)來(lái)檢測(cè)他們會(huì)返回False。要使用inspect.isawaitable()來(lái)檢測(cè)他們。3.5 新版功能.
-
class
collections.abc.AsyncIterable? 提供了
__aiter__方法的抽象基類。參見 asynchronous iterable 的定義。3.5 新版功能.
-
class
collections.abc.AsyncIterator? 提供了
__aiter__和__anext__方法的抽象基類。參見 asynchronous iterator 的定義。3.5 新版功能.
-
class
collections.abc.AsyncGenerator? 為異步生成器類提供的抽象基類,這些類實(shí)現(xiàn)了定義在 PEP 525 和 PEP 492 里的協(xié)議。
3.6 新版功能.
這些抽象基類讓我們可以確定類和示例擁有某些特定的函數(shù),例如:
size = None
if isinstance(myvar, collections.abc.Sized):
size = len(myvar)
有些抽象基類也可以用作混入類(mixin),這可以更容易地開發(fā)支持容器 API 的類。例如,要寫一個(gè)支持完整 Set API 的類,只需要提供下面這三個(gè)方法: __contains__(), __iter__() 和 __len__()。抽象基類會(huì)補(bǔ)充上其余的方法,比如 __and__() 和 isdisjoint():
class ListBasedSet(collections.abc.Set):
''' Alternate set implementation favoring space over speed
and not requiring the set elements to be hashable. '''
def __init__(self, iterable):
self.elements = lst = []
for value in iterable:
if value not in lst:
lst.append(value)
def __iter__(self):
return iter(self.elements)
def __contains__(self, value):
return value in self.elements
def __len__(self):
return len(self.elements)
s1 = ListBasedSet('abcdef')
s2 = ListBasedSet('defghi')
overlap = s1 & s2 # The __and__() method is supported automatically
當(dāng)把 Set 和 MutableSet 用作混入類時(shí)需注意:
由于某些集合操作會(huì)創(chuàng)建新集合,默認(rèn)的混入方法需要一種從可迭代對(duì)象里創(chuàng)建新實(shí)例的方法。假如其類構(gòu)造函數(shù)簽名形如
ClassName(iterable),則其會(huì)調(diào)用一個(gè)內(nèi)部的類方法_from_iterable(),其中調(diào)用了cls(iterable)來(lái)生成一個(gè)新集合。如果這個(gè)Set混入類在類中被使用,但其構(gòu)造函數(shù)的簽名卻是不同的形式,那么你就需要重載_from_iterable()方法,將其編寫成一個(gè)類方法,并且它能夠從可迭代對(duì)象參數(shù)中構(gòu)造一個(gè)新實(shí)例。重載比較符時(shí)時(shí)(想必是為了速度,因?yàn)槠湔Z(yǔ)義都是固定的),只需要重定義
__le__()和__ge__()函數(shù),然后其他的操作會(huì)自動(dòng)跟進(jìn)。混入集合類
Set提供了一個(gè)_hash()方法為集合計(jì)算哈希值,然而,__hash__()函數(shù)卻沒有被定義,因?yàn)椴⒉皇撬屑隙际强晒2⑶也豢勺兊摹榱耸褂没烊腩悶榧咸砑庸D芰?,可以同時(shí)繼承Set()和Hashable()類,然后定義__hash__ = Set._hash。
參見
OrderedSet recipe 是基于
MutableSet構(gòu)建的一個(gè)示例。
