He escrito un objeto contenedor personalizado.
De acuerdo con esta página , necesito implementar este método en mi objeto:
__iter__(self)
Sin embargo, al seguir el enlace a los tipos de iteradores en el manual de referencia de Python, no se dan ejemplos de cómo implementar el suyo.
¿Alguien puede publicar un fragmento (o un enlace a un recurso) que muestre cómo hacer esto?
El contenedor que estoy escribiendo es un mapa (es decir, almacena valores mediante claves únicas). Los dicts se pueden iterar así:
for k, v in mydict.items()
En este caso, necesito poder devolver dos elementos (¿una tupla?) En el iterador. Todavía no está claro cómo implementar dicho iterador (a pesar de las diversas respuestas que se han proporcionado amablemente). ¿Alguien podría arrojar algo más de luz sobre cómo implementar un iterador para un objeto contenedor similar a un mapa? (es decir, una clase personalizada que actúa como un dictado)?
some_list
se hayan obtenido todos los elementos de .some_list
se agote.StopIteration
es generado automáticamente por Python cuando la función generadora regresa, ya sea al llamar explícitamentereturn
o al llegar al final de la función (que como todas las funciones tiene un implícitoreturn None
al final). La elevación explícitaStopIteration
no es necesaria y, a partir de Python 3.5, en realidad no funcionará (consulte PEP 479 ): al igual que los generadores se conviertenreturn
enStopIteration
, se convierten explícitamenteraise StopIteration
en aRuntimeError
.Otra opción es heredar de la clase base abstracta apropiada del módulo de colecciones como se documenta aquí .
En caso de que el contenedor sea su propio iterador, puede heredar de
collections.Iterator
.next
Entonces solo necesitas implementar el método.Un ejemplo es:
Mientras mira el
collections
módulo, considere heredar deSequence
,Mapping
u otra clase base abstracta si es más apropiado. A continuación, se muestra un ejemplo de unaSequence
subclase:NB : Gracias a Glenn Maynard por llamar mi atención sobre la necesidad de aclarar la diferencia entre los iteradores por un lado y los contenedores que son iterables en lugar de iteradores por el otro.
fuente
por lo general,
__iter__()
solo devuelve self si ya has definido el método next () (objeto generador):aquí hay un ejemplo ficticio de un generador:
pero
__iter__()
también se puede utilizar así: http://mail.python.org/pipermail/tutor/2006-January/044455.htmlfuente
Si su objeto contiene un conjunto de datos al que desea vincular el iter de su objeto, puede hacer trampa y hacer esto:
fuente
hasattr
, usetry/except AttributeError
La "interfaz iterable" en Python consta de dos métodos
__next__()
y__iter__()
. La__next__
función es la más importante, ya que define el comportamiento del iterador, es decir, la función determina qué valor debe devolverse a continuación. El__iter__()
método se utiliza para restablecer el punto de inicio de la iteración. A menudo, encontrará que__iter__()
puede regresar a sí mismo cuando__init__()
se usa para establecer el punto de partida.Consulte el siguiente código para definir una clase inversa que implementa la "interfaz iterable" y define un iterador sobre cualquier instancia de cualquier clase de secuencia. El
__next__()
método comienza al final de la secuencia y devuelve valores en orden inverso a la secuencia. Tenga en cuenta que las instancias de una clase que implementa la "interfaz de secuencia" deben definir__len__()
un__getitem__()
método y un método.fuente
Para responder a la pregunta sobre las asignaciones : lo que proporcionó
__iter__
debe iterar sobre las claves de la asignación. El siguiente es un ejemplo simple que crea un mapeox -> x * x
y funciona en Python3 extendiendo el mapeo ABC.fuente
En caso de que no desee heredar
dict
como otros han sugerido, aquí hay una respuesta directa a la pregunta sobre cómo implementar__iter__
para un ejemplo crudo de un dictado personalizado:Eso usa un generador, que está bien descrito aquí .
Dado que heredamos de
Mapping
, también debe implementar__getitem__
y__len__
:fuente
Una opción que podría funcionar para algunos casos es hacer que su clase personalizada hereda de
dict
. Esto parece una elección lógica si actúa como un dict; tal vez debería ser un dict. De esta manera, obtiene una iteración similar a un dictado de forma gratuita.Salida:
fuente
ejemplo para inhert de dict, modifique su
iter
, por ejemplo, salte la tecla2
cuando esté en el bucle forfuente