2016-08-21 2 views
0

В чем конкретно заключается роль iter? Рассмотрим следующий блок кода:Почему в классах нужно использовать метод __iter __()?

class Reverse: 
    def __init__(self,data): 
     self.data = data 
     self.index = len(data) 
    def __iter__(self): 
     return self 
    def next(self): 
     if self.index == 0: 
      raise StopIteration 
     self.index = self.index - 1 
     return self.data[self.index] 

опуская ИТЭР (самообеспечение) и переписано:

class Reverse2: 
    def __init__(self,data): 
     self.data = data 
     self.index = len(data) 
    def next(self): 
     if self.index == 0: 
      raise StopIteration 
     self.index = self.index - 1 
     return self.data[self.index] 

Тогда:

x = [1,2,3] 
y = Reverse(x) 
z = Reverse2(x) 
y.next() 
>>> 3 
y.next() 
>>> 2 
y.next() 
>>> 1 
z.next() 
>>> 3 
z.next() 
>>> 2 
z.next() 
>>> 1 

классы ведут себя так же, независимо от того, включают ли я iter() или нет, так почему я должен включать его в первую очередь? Извините, если мой вопрос непонятен - я просто не знаю, как сформулировать его более ясным образом ...

ответ

0

__iter__ возвращает iterator object, что позволяет преобразовать объект в контейнер, который может быть повторена через for .. in ...

Объект итератора - это любой объект, который определяет метод __next__, который возвращает следующий элемент, если существует, или поднять StopIteration в противном случае.

Хотя __iter__ может возвращать любой такой объект итератора, он может возвратиться сам, если он реализует метод __next__.

Например:

class Reverse: 
    def __init__(self,data): 
     self.data = data 
     self.index = len(data) 
    def __iter__(self): 
     return self 
    def __next__(self): 
     if self.index == 0: 
      raise StopIteration 
     self.index = self.index - 1 
     return self.data[self.index] 

Теперь вы можете использовать в течение цикла:

for xx in Reverse(x): 
    print xx 
+0

ok Я понимаю, почему __iter__ должен быть включен сейчас, но почему я должен заставить этот метод возвращать «я»? –

1

Метод __iter__ всегда вызывается, когда итератор требуется, например, путем явного вызова iter или в for -loops или при создании списков list(xy).

Таким образом, вы не можете использовать свой второй класс Reverse2 во всех этих контекстах.

>>> list(Reverse("abc")) 
['c', 'b', 'a'] 
>>> list(Reverse2("abc")) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: iteration over non-sequence 

Чтобы ответить на этот вопрос в комментарии: __iter__ -метод должен возвращать любой итератор или экземпляр с __next__ -метода. Только если ваш класс итератор сам по себе, он должен вернуть self. Пример возврата генератора в качестве итератора:

class Reverse3: 
    def __init__(self,data): 
     self.data = data 
    def __iter__(self): 
     # returns an generator as iterator 
     for idx in range(len(self.data)-1, -1, -1): 
      yield self.data[idx] 
+0

ok Я понимаю, почему __iter__ должен быть включен сейчас, но почему я должен заставить этот метод возвращать «я»? –

+0

@KevinMoon: см. Мой ответ, но вы также должны отредактировать свой вопрос. – Daniel

Смежные вопросы