2012-03-05 13 views
12

Tengo una clase en python, que tiene una variable de instancia iterable. Quiero iterar las instancias de la clase iterando sobre el iterable incrustado.python hacer que la clase sea iterable al devolver incrustado iterable

he implementado de la siguiente manera:

def __iter__(self): 
    return self._iterable.__iter__() 

Yo no me siento tan cómodo llamando al método __iter__() en el iterable, ya que es un método especial. ¿Es así como resolverías este problema en python o hay una solución más elegante?

+1

Es posible que desee vigilar PEP 380 (http://www.python.org/dev/peps/pep-0380/), que lo hará posible con '' rendimiento de self._iterable'' (esto se acepta para su inclusión en 3.3). –

Respuesta

22

El "mejor" a manera de delegar __iter__ sería:

def __iter__(self): 
    return iter(self._iterable) 

Alternativamente, podría ser vale la pena conocer:

def __iter__(self): 
    for item in self._iterable: 
     yield item 

que le permitirá jugar con cada artículo antes de regresar (por ejemplo, si quería yield item * 2).

Y como @Lattyware menciona en los comentarios, PEP380 (programado para su inclusión en Python 3.3) permitirá:

def __iter__(self): 
    yield from self._iterable 

en cuenta que puede ser tentador para hacer algo como:

def __init__(self, iterable): 
    self.__iter__ = iterable.__iter__ 

Pero este no funcionará: iter(foo) llama al método __iter__ en type(foo) directamente, sin pasar por foo.__iter__. Consideremos, por ejemplo:

class SurprisingIter(object): 
    def __init__(self): 
     self.__iter__ = lambda self: iter("abc") 

    def __iter__(self): 
     return iter([1, 2, 3]) 

que se puede esperar que list(SurprisingIter()) volvería ["a", "b", "c"], pero en realidad devuelve [1, 2, 3].

+0

sí, gracias - ¡eso se ve mejor! – jzwiener

+0

¡Muy buena descripción general! – kindall

+0

Hay un error tipográfico en la variante PEP380, que prefiero. Debe ser 'def __iter __ (self): yield from self._iterable' – kap

Cuestiones relacionadas