2013-11-22 2 views
0

Я забираю пользовательский класс под названием queue, который использует итератор. У меня есть Iterator class в отдельном файле iterator.py. Я получаю ошибку ниже, когда я пытаюсь выполнить итерацию с помощью цикла.Итератор на пользовательских классах в python throws error in python

from iterator import Iterator 
    class Abstractstruc(object): 
     def __init__(self): 
      assert False 
     def __str__(self): 
      return "<%s: %s>" %(self.__class__.__name__,self.container) 

class Queue(Abstractstruc,Iterator): 

    def __init__(self, objecttype=object): 
     self.container=[] 
     self.size=0 

    def add(self, data): 
     self.container.append(data) 


    def remove(self): 
     self.container.pop(0) 


    def __getitem__(self,index): 
     return self.container[index] 


    def __iter__(self): 
     return Iterator(self.container) 

if __name__=='__main__': 

    q=Queue(int) 
    q.add(5) 
    q.add(4) 
    q.add(6) 

    for i in q: 
     print i 

iterator.py

class Iterator(object): 
    def __init__(self, wrapped): 
     self.wrapped = wrapped 
     self.offset = 0 

    def __next__(self): 
     if self.offset>=len(self.wrapped): 
      raise StopIteration 
     else: 
      item = self.wrapped[self.offset] 
      self.offset+=1 
      return item 

Я получаю сообщение об ошибке

<Queue: [5, 4, 6]> 
<Queue: [4, 6]> 
4 
Traceback (most recent call last): 
    File "queue.py", line 78, in <module> 
    for i in q: 
TypeError: iter() returned non-iterator of type 'Iterator' 

Я не понимаю, почему он не возвращает итератор. какие исправления нужны здесь?

+0

См http://docs.python.org/3/library/stdtypes.html#iterator-types: * Итератор сами объекты должны поддерживать следующие два метода, которые вместе образуют протокол итератора * , показывая, что вам нужно реализовать '__next__' и' __iter__'. –

+0

@MartijnPieters - изменилось ли написание '__next__' с Python2 на Python3? Ничего, я вижу, что так оно и было. В Python2 необходимо реализовать 'Iterator.next()'; в Python3 это 'Iterator .__ next __()'. –

+0

@ Robᵩ: он сделал; он был переименован из '.next()' в '.__ next __()'. –

ответ

1

Это потому, что метод next() не должен быть волшебным, вам не нужны двойные подчеркивания. Как упоминалось ранее, Python 3 отличается.

def next(self): 
+1

Хорошее наблюдение, но здесь есть тонко. В Python3 одному _does_ нужны символы подчеркивания. Возможно, OP читал некоторые документы Python3 и не понимал, что они полностью применимы. –

+0

Я изменил свой комментарий. Спасибо за совет! Я должен определенно приблизиться к Python3. – rocknrollnerd

3

Итераторы должны сами реализовать __iter__. Они могут просто вернуть self. От docs обратите внимание, что пользовательские объекты итератора должны поддерживать __iter__ для поддержки for и in операторов. Кроме того, как отметил @ Robᵩ, поскольку вы используете Python 2 вместо 3, вам нужно реализовать next(), а не __next__().

+1

Кроме того, мы можем сделать вывод из его утверждения 'print', что он использует Python2. Поэтому ему нужно переименовать '.__ next __()' в '.next()'. –

+0

@ Robᵩ Хороший улов в выводе версии Python. Я добавил его уже, но я отрегулирую дополнение к учетной записи для этого. –

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