web-dev-qa-db-ja.com

Pythonイテレータクラスの定義、「iter()は 'Fib'タイプの非イテレータを返しました」で失敗しました

python 2.7とipython2.7を使用しています。ipythonで試してみました:

class Fib(object):
    def __init__(self, max):
        super(Fib, self).__init__()
        self.max = max

    def __iter__(self):
        self.a = 0
        self.b = 1
        return self

    def __next__(self):
        fib = self.a
        if fib > self.max:
            raise StopIteration
        self.a, self.b = self.b, self.a + self.b
        return fib

def main():
    fib = Fib(100)
    for i in fib:
        print i

if __name__ == '__main__':
    main()

まあそれはエラーを報告します:

TypeErrorトレースバック(最新の呼び出しは最後)()22 23 if name == 'main':---> 24 main()25

<ipython-input-21-f10bd2d06666> in main()
    18 def main():
    19     fib = Fib(100)
---> 20     for i in fib:
    21         print i
    22

TypeError: iter() returned non-iterator of type 'Fib'

このコードは実際にはインターネットからのものです。グラマは私には問題ないようですが、問題はどのように発生しますか?

ありがとう。

15
Troskyvs

def __next__(self)はPython 3

Python 2の場合、メソッドnext()を追加する必要があります

このコードはPython 3とPython 2:

class Fib(object):
    def __init__(self, max):
        super(Fib, self).__init__()
        self.max = max

    def __iter__(self):
        self.a = 0
        self.b = 1
        return self

    def __next__(self):
        fib = self.a
        if fib > self.max:
            raise StopIteration
        self.a, self.b = self.b, self.a + self.b
        return fib

    def next(self):
        return self.__next__()


def main():
    fib = Fib(100)
    for i in fib:
        print(i)

if __name__ == '__main__':
    main()
35
KromviellBlack

これは、python 3イテレータプロトコルが___next___メソッドを使用する3つのコードです。最善の修正方法は、python 3.の使用を開始することです。ただし、必要な場合= python 2、____next___をnextに変更するだけです。変更の理由は、nextなどのマジックメソッドが____命名規則。

2
tdelaney