2013-11-22 24 views
0

我是一個使用迭代器的稱爲隊列的自定義類。我在一個名爲iterator.py的獨立文件中有一個Iterator class。當我嘗試迭代使用for循環時,出現以下錯誤。Python中的自定義類的迭代器在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__以支持forin語句。另外,正如@Robᵩ指出的那樣,由於您使用的是Python 2而不是3,因此您需要實現next()而不是__next__()

+1

另外,我們可以從他的'print'語句推斷出他正在使用Python2。所以他需要將'.__ next __()'重命名爲'.next()'。 –

+0

@Robᵩ在Python版本的推理中很好地捕捉到了。我已經添加了它,但我會調整添加來解決這個問題。 –