"collections.abc" --- Clases Base Abstractas para Contenedores
**************************************************************

Nuevo en la versión 3.3: Anteriormente, este módulo formaba parte del
módulo "collections".

**Código fuente:** Lib/_collections_abc.py

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

This module provides *abstract base classes* that can be used to test
whether a class provides a particular interface; for example, whether
it is *hashable* or whether it is a mapping.

Una prueba "issubclass()" o "isinstance()" para una interfaz funciona
de tres 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

En este ejemplo, la clase "D" no necesita definir "__contains__",
"__iter__" y "__reversed__" porque el operador in, la lógica de
*iteración* y la función "reversed()" recurren automáticamente al uso
de "__getitem__" y "__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__(next): ...

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

Las interfaces complejas no admiten esta última técnica porque una
interfaz es más que la simple presencia de nombres de métodos. Las
interfaces especifican la semántica y las relaciones entre métodos que
no se pueden inferir únicamente de la presencia de nombres de métodos
específicos. Por ejemplo, saber que una clase proporciona
"__getitem__", "__len__" y "__iter__" no es suficiente para distinguir
un "Sequence" de un "Mapping".

Nuevo en la versión 3.9: These abstract classes now support "[]". See
Tipo Alias Genérico and **PEP 585**.


Colecciones Clases Base Abstractas
==================================

El módulo de colecciones ofrece lo siguiente *ABCs*:

+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| ABC                            | Hereda de              | Métodos Abstractos      | 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__",          | Métodos heredados "Sequence" y "append", "reverse",  |
|                                |                        | "__setitem__",          | "extend", "pop", "remove", and "__iadd__"            |
|                                |                        | "__delitem__",          |                                                      |
|                                |                        | "__len__", "insert"     |                                                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "ByteString"                   | "Sequence"             | "__getitem__",          | Métodos heredados "Sequence"                         |
|                                |                        | "__len__"               |                                                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "Set"                          | "Collection"           | "__contains__",         | "__le__", "__lt__", "__eq__", "__ne__", "__gt__",    |
|                                |                        | "__iter__", "__len__"   | "__ge__", "__and__", "__or__", "__sub__", "__xor__", |
|                                |                        |                         | and "isdisjoint"                                     |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "MutableSet"                   | "Set"                  | "__contains__",         | Métodos heredados "Set" y "clear", "pop", "remove",  |
|                                |                        | "__iter__", "__len__",  | "__ior__", "__iand__", "__ixor__", and "__isub__"    |
|                                |                        | "add", "discard"        |                                                      |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "Mapping"                      | "Collection"           | "__getitem__",          | "__contains__", "keys", "items", "values", "get",    |
|                                |                        | "__iter__", "__len__"   | "__eq__", and "__ne__"                               |
+--------------------------------+------------------------+-------------------------+------------------------------------------------------+
| "MutableMapping"               | "Mapping"              | "__getitem__",          | Métodos heredados "Mapping" y "pop", "popitem",      |
|                                |                        | "__setitem__",          | "clear", "update", and "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 al pie ]-

[1] Estos ABC anulan "object.__subclasshook__()" para admitir la
    prueba de una interfaz verificando que los métodos requeridos
    estén presentes y no se hayan configurado en "None". Esto solo
    funciona para interfaces simples. Las interfaces más complejas
    requieren registro o herencia directa.

[2] La verificación de "isinstance(obj, Iterable)" detecta clases que
    están registradas como "Iterable" o que tienen un método
    "__iter__()", pero no detecta clases que iteran con el método
    "__getitem__()". La única forma confiable de determinar si un
    objeto es *iterable* es llamar a "iter(obj)".


Colecciones Clases base abstractas - Descripciones detalladas
=============================================================

class collections.abc.Container

   ABC para clases que proporcionan el método "__contains__()".

class collections.abc.Hashable

   ABC para clases que proporcionan el método "__hash__()".

class collections.abc.Sized

   ABC para clases que proporcionan el método "__len__()".

class collections.abc.Callable

   ABC para clases que proporcionan el método "__call__()".

class collections.abc.Iterable

   ABC para clases que proporcionan el método "__iter__()".

   Al marcar "isinstance(obj, Iterable)" se detectan las clases que
   están registradas como "Iterable" o que tienen un método
   "__iter__()", pero no detecta clases que iteran con el método
   "__getitem__()". La única forma confiable de determinar si un
   objeto es *iterable* es llamar a "iter(obj)".

class collections.abc.Collection

   ABC para clases de contenedor iterables de tamaño.

   Nuevo en la versión 3.6.

class collections.abc.Iterator

   ABC para clases que proporcionan el método "__iter__()" y
   "__next__()". Ver también la definición de *iterator*.

class collections.abc.Reversible

   ABC para clases iterables que también proporcionan "__reversed__()"
   method.

   Nuevo en la versión 3.6.

class collections.abc.Generator

   ABC para clases generadoras que implementan el protocolo definido
   en **PEP 342** que extiende los iteradores con los métodos
   "send()", "throw()" and "close()". Ver también la definición de
   *generator*.

   Nuevo en la versión 3.5.

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

   ABC para solo lectura y mutable *secuencias*.

   Nota de implementación: algunos de los métodos mixin, tales como
   "__iter__()", "__reversed__()" and "index()", hacen llamadas
   repetidas al subyacente "__getitem__()" method. En consecuencia, si
   "__getitem__()" se implementa con velocidad de acceso constante,
   los métodos mixin tendrán un rendimiento lineal; sin embargo, si el
   método subyacente es lineal (como lo sería con una lista
   vinculada), los mixins tendrán un rendimiento cuadrático y
   probablemente deberán ser anulados.

   Distinto en la versión 3.5: El método index() agregó soporte para
   los argumentos *stop* y *start*.

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

   ABC para conjuntos de solo lectura y mutables.

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

   ABC para solo lectura y mutable *mapeos*.

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

   ABC para mapeo, elementos, claves y valores *vistas*.

class collections.abc.Awaitable

   ABC para objetos *awaitable*, que pueden ser usados en expresiones
   "await". Las implementaciones personalizadas deben proporcionar el
   método "__await__()".

   *Coroutine* objetos e instancias de la clase "Coroutine" ABC son
   todas las instancias de este ABC.

   Nota:

     En CPython, las corrutinas basadas en generador (generadores
     decorados con "types.coroutine()" o "asyncio.coroutine()") son
     *awaitables*, a pesar de que no tienen un método "__await__()".
     El uso de "isinstance(gencoro, Awaitable)" para ellos retornará
     "False". Use "inspect.isawaitable()" para detectarlos.

   Nuevo en la versión 3.5.

class collections.abc.Coroutine

   ABC para clases corrutinas compatibles. Estos implementan los
   siguientes métodos, definidos en Objetos de Corrutina: "send()",
   "throw()", and "close()". Las implementaciones personalizadas
   también deben implementar "__await__()". Todas las instancias de
   "Coroutine" también son instancias de "Awaitable". Ver también la
   definición de *coroutine*.

   Nota:

     En CPython, las corrutinas basadas en generador (generadores
     decorados con "types.coroutine()" o "asyncio.coroutine()") son
     *awaitables*, a pesar de que no tienen un método "__await__()".
     El uso de "isinstance(gencoro, Coroutine)" para ellos retornará
     "False". Use "inspect.isawaitable()" para detectarlos.

   Nuevo en la versión 3.5.

class collections.abc.AsyncIterable

   ABC para las clases que proporcionan el método "__aiter__". Ver
   también la definición de *asynchronous iterable*.

   Nuevo en la versión 3.5.

class collections.abc.AsyncIterator

   ABC para clases que proveen métodos "__aiter__" and "__anext__".
   Ver también la definición de *asynchronous iterator*.

   Nuevo en la versión 3.5.

class collections.abc.AsyncGenerator

   ABC para clases generadoras asincrónicas que implementan el
   protocolo definido en **PEP 525** y **PEP 492**.

   Nuevo en la versión 3.6.


Ejemplos y Recetas
==================

Los ABC nos permiten preguntar a las clases o instancias si brindan
una funcionalidad particular, por ejemplo:

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

Varios ABCs también son útiles como mixins que facilitan el desarrollo
de clases que admiten APIs de contenedor. Por ejemplo, para escribir
una clase que admita toda la API "Set", solo es necesario proporcionar
los tres métodos abstractos subyacentes: "__contains__()",
"__iter__()", y "__len__()". El ABC proporciona los métodos restantes,
como "__and__()" y "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 el uso de "Set" y "MutableSet" como un mixin:

1. Dado que algunas operaciones de conjuntos crean nuevos conjuntos,
   los métodos mixin predeterminados necesitan una forma de crear
   nuevas instancias a partir de un iterable. Se supone que el
   constructor de la clase tiene una firma con el formato
   "ClassName(iterable)". Esa suposición se factoriza en un método de
   clase interno llamado "_from_iterable()" que llama a
   "cls(iterable)" para producir un nuevo conjunto. Si el mixin "Set"
   se está usando en una clase con una firma de constructor diferente,
   necesitarás anular "_from_iterable()" con un método de clase o
   método regular que pueda construir nuevas instancias a partir de un
   argumento iterable.

2. Para reemplazar las comparaciones (presumiblemente para la
   velocidad, ya que las semánticas son fijas), redefinir "__le__()" y
   "__ge__()", luego las otras operaciones seguirán automáticamente su
   ejemplo.

3. The "Set" mixin provides a "_hash()" method to compute a hash value
   for the set; however, "__hash__()" is not defined because not all
   sets are *hashable* or immutable.  To add set hashability using
   mixins, inherit from both "Set()" and "Hashable()", then define
   "__hash__ = Set._hash".

Ver también:

  * OrderedSet receta para un ejemplo basado en "MutableSet".

  * Para obtener más información sobre ABCs, ver el módulo "abc" y
    **PEP 3119**.
