collections.abc — 容器的抽象基类

3.3 版本新增: 此模块以前是 collections 模块的一部分。

源代码: Lib/_collections_abc.py


此模块提供了抽象基类,可用于测试一个类是否提供了特定的接口;例如,它是否可哈希或是否是映射

对接口的 issubclass()isinstance() 测试以三种方式之一工作。

1) 新编写的类可以直接从其中一个抽象基类继承。该类必须提供所需的抽象方法。其余的混合方法来自继承,并且可以根据需要进行重写。其他方法可以根据需要添加

class C(Sequence):                      # Direct inheritance
    def __init__(self): ...             # Extra method not required by the ABC
    def __getitem__(self, index):  ...  # Required abstract method
    def __len__(self):  ...             # Required abstract method
    def count(self, value): ...         # Optionally override a mixin method
>>> issubclass(C, Sequence)
True
>>> isinstance(C(), Sequence)
True

2) 现有类和内置类可以注册为 ABC 的“虚拟子类”。这些类应定义完整的 API,包括所有抽象方法和所有混合方法。这允许用户依靠 issubclass()isinstance() 测试来确定是否支持完整的接口。此规则的例外情况是那些可以从 API 的其余部分自动推断出来的方法

class D:                                 # No inheritance
    def __init__(self): ...              # Extra method not required by the ABC
    def __getitem__(self, index):  ...   # Abstract method
    def __len__(self):  ...              # Abstract method
    def count(self, value): ...          # Mixin method
    def index(self, value): ...          # Mixin method

Sequence.register(D)                     # Register instead of inherit
>>> issubclass(D, Sequence)
True
>>> isinstance(D(), Sequence)
True

在此示例中,类 D 不需要定义 __contains____iter____reversed__,因为in 运算符迭代逻辑和 reversed() 函数会自动回退到使用 __getitem____len__

3) 一些简单的接口可以通过存在所需的方法直接识别(除非这些方法已设置为 None

class E:
    def __iter__(self): ...
    def __next__(self): ...
>>> issubclass(E, Iterable)
True
>>> isinstance(E(), Iterable)
True

复杂的接口不支持最后一种技术,因为接口不仅仅是存在方法名称。接口指定了方法之间的语义和关系,这些语义和关系不能仅从特定方法名称的存在来推断。例如,知道一个类提供 __getitem____len____iter__ 不足以区分 SequenceMapping

3.9 版本新增: 这些抽象类现在支持 []。请参阅泛型别名类型PEP 585

集合抽象基类

集合模块提供以下ABCs

ABC

继承自

抽象方法

混合方法

Container [1]

__contains__

Hashable [1]

__hash__

Iterable [1] [2]

__iter__

Iterator [1]

可迭代 (Iterable)

__next__

__iter__

Reversible [1]

可迭代 (Iterable)

__reversed__

Generator [1]

迭代器 (Iterator)

send, throw

close, __iter__, __next__

Sized [1]

__len__

Callable [1]

__call__

Collection [1]

Sized, Iterable, Container

__contains__, __iter__, __len__

序列 (Sequence)

Reversible, Collection

__getitem__, __len__

__contains__, __iter__, __reversed__, index, 和 count

可变序列 (MutableSequence)

序列 (Sequence)

__getitem__, __setitem__, __delitem__, __len__, insert

继承的 Sequence 方法和 append, clear, reverse, extend, pop, remove, 和 __iadd__

字节串 (ByteString)

序列 (Sequence)

__getitem__, __len__

继承的 Sequence 方法

集合 (Set)

集合 (Collection)

__contains__, __iter__, __len__

__le__, __lt__, __eq__, __ne__, __gt__, __ge__, __and__, __or__, __sub__, __xor__, 和 isdisjoint

可变集合 (MutableSet)

集合 (Set)

__contains__, __iter__, __len__, add, discard

继承自 Set 的方法以及 clear, pop, remove, __ior__, __iand__, __ixor____isub__

映射 (Mapping)

集合 (Collection)

__getitem__, __iter__, __len__

__contains__, keys, items, values, get, __eq____ne__

可变映射 (MutableMapping)

映射 (Mapping)

__getitem__, __setitem__, __delitem__, __iter__, __len__

继承自 Mapping 的方法以及 pop, popitem, clear, updatesetdefault

映射视图 (MappingView)

有尺寸 (Sized)

__len__

项视图 (ItemsView)

MappingView, Set

__contains__, __iter__

键视图 (KeysView)

MappingView, Set

__contains__, __iter__

值视图 (ValuesView)

MappingView, Collection

__contains__, __iter__

Awaitable [1]

__await__

Coroutine [1]

可等待 (Awaitable)

send, throw

close

AsyncIterable [1]

__aiter__

AsyncIterator [1]

异步可迭代 (AsyncIterable)

__anext__

__aiter__

AsyncGenerator [1]

异步迭代器 (AsyncIterator)

asend, athrow

aclose, __aiter__, __anext__

Buffer [1]

__buffer__

脚注

集合抽象基类 – 详细描述

class collections.abc.Container

为提供 __contains__() 方法的类提供的 ABC。

class collections.abc.Hashable

为提供 __hash__() 方法的类提供的 ABC。

class collections.abc.Sized

为提供 __len__() 方法的类提供的 ABC。

class collections.abc.Callable

为提供 __call__() 方法的类提供的 ABC。

有关如何在类型注解中使用 Callable 的详细信息,请参见 注解可调用对象

class collections.abc.Iterable

为提供 __iter__() 方法的类提供的 ABC。

检查 isinstance(obj, Iterable) 会检测被注册为 Iterable 或具有 __iter__() 方法的类,但它不会检测使用 __getitem__() 方法进行迭代的类。确定对象是否为 可迭代 的唯一可靠方法是调用 iter(obj)

class collections.abc.Collection

为具有大小的可迭代容器类提供的 ABC。

3.6 版本新增。

class collections.abc.Iterator

为提供 __iter__()__next__() 方法的类提供的 ABC。另请参见 迭代器 的定义。

class collections.abc.Reversible

为也提供 __reversed__() 方法的可迭代类提供的 ABC。

3.6 版本新增。

class collections.abc.Generator

为实现 PEP 342 中定义的协议的 生成器 类提供的 ABC,该协议使用 send()throw()close() 方法扩展了 迭代器

有关在类型注解中使用 Generator 的详细信息,请参阅 注解生成器和协程

3.5 版本新增。

class collections.abc.Sequence
class collections.abc.MutableSequence
class collections.abc.ByteString

用于只读和可变序列的 ABC。

实现说明:一些混入方法,例如 __iter__()__reversed__()index(),会重复调用底层 __getitem__() 方法。因此,如果 __getitem__() 的实现具有恒定的访问速度,则混入方法将具有线性性能;但是,如果底层方法是线性的(就像链表一样),则混入方法将具有二次性能,并且可能需要被覆盖。

在 3.5 版本中变更: index() 方法增加了对 stopstart 参数的支持。

自 3.12 版本起弃用,将在 3.14 版本中移除: ByteString ABC 已被弃用。在类型标注中使用时,请优先使用联合类型,例如 bytes | bytearraycollections.abc.Buffer。作为 ABC 使用时,请优先使用 Sequencecollections.abc.Buffer

class collections.abc.Set
class collections.abc.MutableSet

用于只读和可变 集合 的 ABC。

class collections.abc.Mapping
class collections.abc.MutableMapping

用于只读和可变 映射 的 ABC。

class collections.abc.MappingView
class collections.abc.ItemsView
class collections.abc.KeysView
class collections.abc.ValuesView

用于映射、条目、键和值的 视图 的 ABC。

class collections.abc.Awaitable

用于 可等待 对象的 ABC,可以在 await 表达式中使用。自定义实现必须提供 __await__() 方法。

协程 对象和 Coroutine ABC 的实例都是此 ABC 的实例。

注意

在 CPython 中,基于生成器的协程(使用 @types.coroutine 装饰的生成器)是可等待的,即使它们没有 __await__() 方法。对它们使用 isinstance(gencoro, Awaitable) 将返回 False。使用 inspect.isawaitable() 来检测它们。

3.5 版本新增。

class collections.abc.Coroutine

用于 协程 兼容类的 ABC。这些类实现了 协程对象 中定义的以下方法:send()throw()close()。自定义实现还必须实现 __await__()。所有 Coroutine 实例也是 Awaitable 的实例。

注意

在 CPython 中,基于生成器的协程(使用 @types.coroutine 装饰的生成器)是可等待的,即使它们没有 __await__() 方法。对它们使用 isinstance(gencoro, Coroutine) 将返回 False。使用 inspect.isawaitable() 来检测它们。

有关在类型标注中使用 Coroutine 的详细信息,请参阅 标注生成器和协程。类型参数的变异性和顺序与 Generator 的类型参数相对应。

3.5 版本新增。

class collections.abc.AsyncIterable

用于提供 __aiter__ 方法的类的 ABC。另请参阅 异步可迭代 的定义。

3.5 版本新增。

class collections.abc.AsyncIterator

用于提供 __aiter____anext__ 方法的类的 ABC。另请参阅 异步迭代器 的定义。

3.5 版本新增。

class collections.abc.AsyncGenerator

用于实现 PEP 525PEP 492 中定义的协议的 异步生成器 类的 ABC。

有关在类型标注中使用 AsyncGenerator 的详细信息,请参阅 标注生成器和协程

3.6 版本新增。

class collections.abc.Buffer

为提供 __buffer__() 方法的类提供的 ABC(抽象基类),实现了 缓冲区协议。请参阅 PEP 688

3.12 版本新增。

示例和技巧

ABC 允许我们询问类或实例是否提供了特定功能,例如:

size = None
if isinstance(myvar, collections.abc.Sized):
    size = len(myvar)

许多 ABC 也可用作混入类,以便更容易开发支持容器 API 的类。例如,要编写一个支持完整 Set API 的类,只需提供三个底层抽象方法:__contains__()__iter__()__len__()。ABC 提供其余方法,例如 __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

关于使用 SetMutableSet 作为混入类的说明

  1. 由于某些集合操作会创建新的集合,默认的混入方法需要一种方法来从一个 可迭代对象 创建新实例。假设类的构造函数具有 ClassName(iterable) 形式的签名。该假设被分解为一个内部的 classmethod,称为 _from_iterable(),它调用 cls(iterable) 来生成一个新的集合。如果 Set 混入类被用于具有不同构造函数签名的类中,则需要使用一个可以从可迭代参数构造新实例的类方法或常规方法来覆盖 _from_iterable()

  2. 要覆盖比较(可能是为了提高速度,因为语义是固定的),请重新定义 __le__()__ge__(),然后其他操作将自动跟进。

  3. Set 混入类提供了一个 _hash() 方法来计算集合的哈希值;但是,__hash__() 没有定义,因为并非所有集合都是 可哈希的 或不可变的。要使用混入类添加集合的可哈希性,请同时继承自 Set()Hashable(),然后定义 __hash__ = Set._hash

另请参阅