6.1 集合的抽象基类

    collections.abc模块提供了很多抽象基类,这些类将集合分解成许多互相独立的属性集。

    即使不深入地考虑不同的属性以及它们和set类以及dict类的关系,我们仍然可以顺利地使用list类。但是,一旦我们开始探究这些抽象基类,就会发现这些类有一些微妙之处。由于将集合的不同概念独立地分解出来,即使在不同的数据结构之间,我们也可以看到一些重复的地方,但却都声称自己是优雅的多态实现。

    在这些基类的最后是一些“只会一招的小马”(one-trick pony)定义。这些只包含一个特殊方法的基类有如下几种。

    • Container基类要求子类实现contains()方法,这个特殊方法实现了in运算符。
    • Iterable基类要求子类实现iter()方法。for语句、生成器表达式和iter()函数都需要使用这个方法。
    • Sized基类要求子类实现len()方法。len()函数需要使用这个方法,它也很稳妥地实现了bool()方法,但是这个方法不是必需的。
    • Hashable基类要求子类实现hash()方法。hash()函数需要使用这个方法,如果这个方法被实现了,就意味着当前对象是不可变的。

    这些抽象基类都是用来建立可以直接在我们的程序中使用且层次更高的复合结构。这些复合结构包括了低层次的基类SizedIterableContainer。下面是一些可能在程序中直接使用的复合基类。

    • Sequence和MutableSequence类,它们是基于例如index()、count()、reverse()、extend()和remove()这些方法创建的,同时也包含了这些方法的实现。
    • Mapping和MutableMapping类,这两个类包含了例如keys()、items()、values()、get()和其他的一些方法的实现。
    • Set和MutableSet类包含了用于set类型的比较操作和算术运算符的实现。

    如果我们深入地探究一下内置的集合,我们就能发现抽象基类是如何组织我们需要重写或者修改的特殊方法的。