A pesar de leerlo, todavía no entiendo cómo funciona __iter__. ¿Cuál sería una explicación simple?

He visto def__iter__(self): return self. No veo cómo funciona esto o los pasos sobre cómo funciona.

20
sss 23 oct. 2009 a las 02:30

5 respuestas

La mejor respuesta

Un iterador necesita definir dos métodos: __iter__() y __next__() (next() en python2). Por lo general, el objeto en sí define el método __next__() o next(), por lo que simplemente se devuelve como el iterador. Esto crea un iterable que también es un iterador . Estos métodos son utilizados por las declaraciones for y in.

8
margincall 26 may. 2018 a las 17:22

En Python, un iterador es cualquier objeto que admite el protocolo del iterador. Parte de ese protocolo es que el objeto debe tener un método __iter__() que devuelve el objeto iterador. Supongo que esto le brinda cierta flexibilidad para que un objeto pueda pasar las responsabilidades del iterador a una clase interna, o crear algún objeto especial. En cualquier caso, el método __iter__() generalmente solo tiene una línea y esa línea a menudo es simplemente return self

La otra parte del protocolo es el método next(), y aquí es donde se realiza el trabajo real. Este método tiene que descubrir o crear u obtener lo siguiente y devolverlo. Es posible que deba realizar un seguimiento de dónde está para que la próxima vez que se llame, realmente devuelva lo siguiente.

Una vez que tenga un objeto que devuelva lo siguiente en una secuencia, puede contraer un bucle for que se vea así:

myname = "Fredericus"
x = []
for i in [1,2,3,4,5,6,7,8,9,10]:
   x.append(myname[i-1])
   i = i + 1 # get the next i
print x

En esto:

myname = "Fredericus"
x = [myname[i] for i in range(10)]
print x

Observe que no hay ningún lugar donde tengamos código que obtenga el siguiente valor de i porque el rango (10) es un objeto que SIGUE el protocolo iterador, y la comprensión de la lista es una construcción que UTILIZA el protocolo iterador.

También puede USAR el protocolo iterador directamente. Por ejemplo, cuando escribo scripts para procesar archivos CSV, a menudo escribo esto:

mydata = csv.reader(open('stuff.csv')
mydata.next()
for row in mydata:
    # do something with the row.

Estoy usando el iterador directamente llamando a next() para omitir la fila del encabezado, luego lo uso indirectamente a través del operador incorporado in en la declaración for.

2
Michael Dillon 22 oct. 2009 a las 23:02

Una clase que admita el método __iter__ devolverá una instancia de objeto iterador: un objeto que admita el método next () . Este objeto será útil en las declaraciones "para" y "en".

3
jldupont 22 oct. 2009 a las 22:43

Las especificaciones para def __iter__(self): son: devuelve un iterador. Entonces, si self es un iterador, return self es claramente apropiado.

"Ser un iterador" significa "tener un método __next__(self)" (en Python 3; en Python 2, desafortunadamente el nombre del método en cuestión es simple next, claramente un error de diseño de nombre para un especial método).

En Python 2.6 y versiones posteriores, la mejor manera de implementar un iterador es generalmente usar la clase base abstracta apropiada de la biblioteca estándar collections module - en Python 2.6, el código podría ser (recuerde llamar al método __next__ en su lugar en Python 3):

import collections

class infinite23s(collections.Iterator):
  def next(self): return 23

Una instancia de esta clase devolverá infinitas copias de 23 cuando se repita (como itertools.repeat(23)), por lo que el ciclo debe finalizar de otra manera. El punto es que la subclasificación collections.Iterator agrega el método correcto __iter__ en su nombre, no es un gran problema aquí, pero es un buen principio general (evite el código repetitivo repetitivo como el de una línea estándar de iteradores {{ X4}} - en repetición, ¡no hay valor agregado y mucho valor restado! -).

6
Alex Martelli 23 oct. 2009 a las 02:10

Tan simple como puedo decirlo:

__iter__ define un método en una clase que devolverá un iterador (un objeto que produce sucesivamente el siguiente elemento contenido por su objeto).

El objeto iterador que devuelve __iter__() puede ser prácticamente cualquier objeto, siempre que defina un método next().

El método next se llamará mediante declaraciones como for ... in ... para obtener el siguiente elemento, y next() debería generar la excepción StopIteration cuando no haya más elementos.

Lo bueno de esto es que le permite a usted definir cómo se itera su objeto, y __iter__ proporciona una interfaz común con la que todas las demás funciones de Python saben cómo trabajar.

27
Gabriel Hurley 13 nov. 2010 a las 09:29