Red de conocimiento informático - Problemas con los teléfonos móviles - Por qué es necesario implementar iteradores en Python

Por qué es necesario implementar iteradores en Python

Esta es una pregunta relacionada con el polimorfismo. Hay dos conceptos sobre la iteración en Python. El primero es Iterable y el segundo es Iterator. El protocolo estipula que el método __iter__ de Iterable devolverá un Iterador y el método __next__ de Iterator. Python 2) devolverá la siguiente iteración o generará una excepción StopIteration si la iteración finaliza.

Al mismo tiempo, el propio Iterator también es un Iterable, por lo que necesita implementar la interfaz Iterable __iter__ para que ambos puedan usarse en for. De esta forma funcionará el siguiente código:

for i in my_list:

...

for i in iter(mylist):

...

para i en (v para v en mylist si v no es Ninguno):

...

Muchos métodos en Python Todos devuelven iteradores directamente, como izip y otros métodos en itertools. Si el iterador en sí no es un Iterable, será muy inconveniente. Primero debe devolver un objeto Iterable y luego dejar que el Iterable regrese al iterador.

Entonces, ¿por qué no mantener la interfaz y el diseño de Iterator en Iterable? Muchos objetos, como listas y dictados, se pueden iterar repetidamente, incluso simultáneamente, y al devolver un iterador separado a través de __iter__ cada vez, puede asegurarse de que las diferentes iteraciones no se afecten entre sí. Los resultados de las expresiones del generador, etc., suelen ser únicos y no se pueden recorrer repetidamente, por lo que devolver un iterador directamente también es una buena opción. Hacer que Iterator sea compatible con ambos Iterable le brinda flexibilidad para elegir qué Iterator devolver.

En resumen, Iterator implementa __iter__ para que sea compatible con la interfaz Iterable, lo que convierte a Iterator en una implementación de Iterable.

Como complemento a la pregunta, la comprensión de for es básicamente correcta, pero todavía hay una ligera desviación: para compatibilidad, en realidad existen dos mecanismos. Si el objeto tiene __iter__, se utilizará un iterador. , pero si el objeto no tiene __iter__, pero implementa __getitem__, se cambiará a iteración de subíndice. Podemos probar esto:

>>> class NotIterable(object):

... def __init__(self, baselist):

... self ._baselist = baselist

... def __getitem__(self, index):

... return self._baselist)

>>> para i en t:

... imprimir i

...

1

2

3

>>> iter(t)

Cuando for descubre que no hay __iter__ pero sí __getitem__, lo hará empezar desde 0 Comience a proceder en secuencia. El método iter también maneja esta situación y devuelve un objeto iterador con subíndice cuando __iter__ no existe. str es un ejemplo importante, ya que las cadenas no tienen una interfaz __iter__.