"collections.abc" --- Classes Base Abstratas para Contêineres
*************************************************************

Novo na versão 3.3: Anteriormente, esse módulo fazia parte do módulo
"collections".

**Código-fonte:** Lib/_collections_abc.py

======================================================================

Esse módulo fornece *classes base abstratas* que podem ser usadas para
testar se uma classe fornece uma interface específica; por exemplo, se
é *hasheável* ou se é um *mapeamento*.

Um teste "issubclass()" ou "isinstance()" para uma interface funciona
em uma das três formas.

1) A newly written class can inherit directly from one of the abstract
base classes.  The class must supply the required abstract methods.
The remaining mixin methods come from inheritance and can be
overridden if desired.  Other methods may be added as needed:

   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) Existing classes and built-in classes can be registered as "virtual
subclasses" of the ABCs.  Those classes should define the full API
including all of the abstract methods and all of the mixin methods.
This lets users rely on "issubclass()" or "isinstance()" tests to
determine whether the full interface is supported.  The exception to
this rule is for methods that are automatically inferred from the rest
of the 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

Neste exemplo, a classe "D" não precisa definir "__contains__",
"__iter__" e "__reversed__" porque o operador in, a lógica *iteration*
e a função "reversed()" retornam automaticamente para o uso de
"__getitem__" e "__len__".

3) Some simple interfaces are directly recognizable by the presence of
the required methods (unless those methods have been set to "None"):

   class E:
       def __iter__(self): ...
       def __next__(self): ...

   >>> issubclass(E, Iterable)
   True
   >>> isinstance(E(), Iterable)
   True

Interfaces complexas não oferecem suporte a esta última técnica porque
uma interface é mais do que apenas a presença de nomes de métodos.
Interfaces especificam semântica e relacionamentos entre métodos que
não podem ser inferidos somente da presença de nomes de métodos
específicos. Por exemplo, saber que uma classe fornece "__getitem__",
"__len__" e "__iter__" é insuficiente para distinguir uma "Sequence"
de uma "Mapping".

Novo na versão 3.9: Essas classes abstratas agora oferecem suporte a
"[]". Veja Tipo Generic Alias e **PEP 585**.


Classes Base Abstratas de Coleções
==================================

O módulo de coleções oferece o seguinte *ABCs*:

+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| ABC                            | Herda de               | Métodos abstratos       | Métodos mixin                                        |
|================================|========================|=========================|======================================================|
| "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",   | "__contains__",         |                                                      |
|                                | "Container"            | "__iter__", "__len__"   |                                                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "Sequence"                     | "Reversible",          | "__getitem__",          | "__contains__", "__iter__", "__reversed__", "index", |
|                                | "Collection"           | "__len__"               | and "count"                                          |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "MutableSequence"              | "Sequence"             | "__getitem__",          | Herdados métodos de "Sequence" e "append", "clear",  |
|                                |                        | "__setitem__",          | "reverse", "extend", "pop", "remove" e "__iadd__"    |
|                                |                        | "__delitem__",          |                                                      |
|                                |                        | "__len__", "insert"     |                                                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "ByteString"                   | "Sequence"             | "__getitem__",          | Herdados métodos de "Sequence"                       |
|                                |                        | "__len__"               |                                                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "Set"                          | "Collection"           | "__contains__",         | "__le__", "__lt__", "__eq__", "__ne__", "__gt__",    |
|                                |                        | "__iter__", "__len__"   | "__ge__", "__and__", "__or__", "__sub__", "__xor__", |
|                                |                        |                         | e "isdisjoint"                                       |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "MutableSet"                   | "Set"                  | "__contains__",         | Herdado "Set" métodos e "clear", "pop", "remove",    |
|                                |                        | "__iter__", "__len__",  | "__ior__", "__iand__", "__ixor__", e "__isub__"      |
|                                |                        | "add", "discard"        |                                                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "Mapping"                      | "Collection"           | "__getitem__",          | "__contains__", "keys", "items", "values", "get",    |
|                                |                        | "__iter__", "__len__"   | "__eq__", e "__ne__"                                 |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "MutableMapping"               | "Mapping"              | "__getitem__",          | Herdado "Mapping" métodos e "pop", "popitem",        |
|                                |                        | "__setitem__",          | "clear", "update", e "setdefault"                    |
|                                |                        | "__delitem__",          |                                                      |
|                                |                        | "__iter__", "__len__"   |                                                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "MappingView"                  | "Sized"                |                         | "__len__"                                            |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "ItemsView"                    | "MappingView", "Set"   |                         | "__contains__", "__iter__"                           |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "KeysView"                     | "MappingView", "Set"   |                         | "__contains__", "__iter__"                           |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "ValuesView"                   | "MappingView",         |                         | "__contains__", "__iter__"                           |
|                                | "Collection"           |                         |                                                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "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__"                   |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+

-[ Notas de rodapé ]-

[1] Essas ABCs substituem "__subclasshook__()" para dar suporte ao
    teste de uma interface verificando se os métodos necessários estão
    presentes e não foram definidos como "None". Isso só funciona para
    interfaces simples. Interfaces mais complexas exigem registro ou
    subclassificação direta.

[2] A verificação "isinstance(obj, Iterable)" detecta classes que são
    registradas como "Iterable" ou que possuem um método "__iter__()",
    mas que não detecta classes que iteram com o método
    "__getitem__()". A única maneira confiável de determinar se um
    objeto é *iterável* é chamar "iter(obj)".


Classes Base Abstrata de Coleções -- Descrições Detalhadas
==========================================================

class collections.abc.Container

   ABC para classes que fornecem o método "__contains__()".

class collections.abc.Hashable

   ABC para classes que fornecem o método "__hash__()".

class collections.abc.Sized

   ABC para classes que fornecem o método "__len__()".

class collections.abc.Callable

   ABC para classes que fornecem o método "__call__()".

class collections.abc.Iterable

   ABC para classes que fornecem o método "__iter__()".

   A verificação "isinstance(obj, Iterable)" detecta classes que são
   registradas como "Iterable" ou que possuem um método "__iter__()",
   mas que não detecta classes que iteram com o método
   "__getitem__()". A única maneira confiável de determinar se um
   objeto é *iterável* é chamar "iter(obj)".

class collections.abc.Collection

   ABC para classes de contêiner iterável de tamanho.

   Novo na versão 3.6.

class collections.abc.Iterator

   ABC para classes que fornecem os métodos "__iter__()" e métodos
   "__next__()". Veja também a definição de *iterator*.

class collections.abc.Reversible

   ABC para classes iteráveis que também fornecem o método
   "__reversed__()".

   Novo na versão 3.6.

class collections.abc.Generator

   ABC para classes *geradores* que implementam o protocolo definido
   em **PEP 342** que estende os *iteradores* com os métodos "send()",
   "throw()" e "close()".

   Novo na versão 3.5.

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

   ABCs para *sequências* somente de leitura e mutáveis.

   Nota de implementação: Alguns dos métodos mixin, como "__iter__()",
   "__reversed__()" e "index()", fazem chamadas repetidas para o
   método subjacente "__getitem__()". Consequentemente, se
   "__getitem__()" for implementado com velocidade de acesso
   constante, os métodos mixin terão desempenho linear; no entanto se
   o método subjacente for linear (como seria com uma lista
   encadeada), os mixins terão desempenho quadrático e provavelmente
   precisará ser substituído.

   Alterado na versão 3.5: O método index() adicionou suporte para os
   argumentos *stop* e *start*.

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

   ABCs para conjuntos somente leitura e mutáveis.

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

   ABCs para somente leitura e mutável *mappings*.

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

   ABCs para mapeamento, itens, chaves e valores *views*.

class collections.abc.Awaitable

   ABC para objetos *aguardáveis*, que podem ser usados em expressões
   de "await". Implementações personalizadas devem fornecer o método
   "__await__()".

   Objetos e instâncias de *corrotina* da ABC "Coroutine" são todas
   instâncias dessa ABC.

   Nota:

     No CPython, as corrotinas baseados em gerador (*geradores*
     decorados com "@types.coroutine") são *aguardáveis*, embora não
     possuam o método "__await__()". Usar "isinstance(gencoro,
     Awaitable)" para eles retornará "False". Use
     "inspect.isawaitable()" para detectá-los.

   Novo na versão 3.5.

class collections.abc.Coroutine

   ABC para classes compatíveis com *corrotina*. Eles implementam os
   seguintes métodos, definidos em Objetos corrotina: "send()",
   "throw()", e "close()". Implementações personalizadas também devem
   implementar "__await__()". Todas as instâncias "Coroutine" também
   são instâncias de "Awaitable".

   Nota:

     No CPython, as corrotinas baseados em gerador (*geradores*
     decorados com "@types.coroutine") são *aguardáveis*, embora não
     possuam o método "__await__()". Usar "isinstance(gencoro,
     Coroutine)" para eles retornará "False". Use
     "inspect.isawaitable()" para detectá-los.

   Novo na versão 3.5.

class collections.abc.AsyncIterable

   ABC para classes que fornecem um método "__aiter__". Veja também a
   definição de *iterável assíncrono*.

   Novo na versão 3.5.

class collections.abc.AsyncIterator

   ABC para classes que fornecem os métodos "__aiter__" e "__anext__".
   Veja também a definição de *iterador assíncrono*.

   Novo na versão 3.5.

class collections.abc.AsyncGenerator

   ABC para classes de *gerador assíncrono* que implementam o
   protocolo definido em **PEP 525** e **PEP 492**.

   Novo na versão 3.6.


Exemplos e receitas
===================

ABCs nos permitem perguntar a classes ou instâncias se elas fornecem
funcionalidades específicas, por exemplo:

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

Vários ABCs também são também úteis como mixins que facilitam o
desenvolvimento de classes que suportam APIs de contêiner. Por
exemplo, para escrever uma classe que suporte toda a API "Set" , é
necessário fornecer apenas os três métodos abstratos subjacentes:
"__contains__()", "__iter__()", e "__len__()". O ABC fornece os
métodos restantes, como "__and__()" e "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

Notas sobre o uso de "Set" e "MutableSet" como um mixin:

1. Como algumas operações de conjunto criam novos conjuntos, os
   métodos de mixin padrão precisam de uma maneira de criar novas
   instâncias a partir de um *iterável*. Supõe-se que a classe
   construtor tenha uma assinatura no formato "ClassName(iterable)".
   Essa suposição é fatorada em um "classmethod" interno chamado
   "_from_iterable()" que chama "cls(iterable)" para produzir um novo
   conjunto. Se o mixin "Set" estiver sendo usado em uma classe com
   uma assinatura de construtor diferente, você precisará substituir
   "_from_iterable()" por um método de classe ou um método regular que
   possa construir novas instâncias a partir de um argumento iterável.

2. Para substituir as comparações (presumivelmente para velocidade, já
   que a semântica é fixa), redefina "__le__()" e "__ge__()", então as
   outras operações seguirão o exemplo automaticamente.

3. O mixin "Set" fornece um método "_hash()" para calcular um valor de
   hash para o conjunto; no entanto, "__hash__()" não é definido
   porque nem todos os conjuntos são *hasheáveis* ou imutáveis. Para
   adicionar hasheabilidade em conjuntos usando mixin, herde de ambos
   "Set()" e "Hashable()", e então defina "__hash__ = Set._hash".

Ver também:

  * OrderedSet receita para um exemplo baseado em "MutableSet".

  * Para mais informações sobre ABCs, consulte o módulo "abc" e **PEP
    3119**.
