たとえば、シリーズを生成するジェネレーターがあります。
def triangleNums():
'''generate series of triangle numbers'''
tn = 0
counter = 1
while(True):
tn = tn + counter
yield tn
counter = counter + 1
python 2.6では、次の呼び出しを行うことができます。
g = triangleNums() # get the generator
g.next() # get next val
ただし、3.0で同じ2行のコードを実行すると、次のエラーが発生します。
AttributeError: 'generator' object has no attribute 'next'
しかし、ループイテレータの構文は3.0で機能します
for n in triangleNums():
if not exitCond:
doSomething...
3.0のこの動作の違いを説明するものはまだ見つかりませんでした。
正しい、g.next()
はg.__next__()
に名前が変更されました。この理由は一貫性です:__init__()
や__del__
などの特別なメソッドにはすべて二重アンダースコア(または現在の専門用語では「アンダー」)があり、.next()
はその少数の例外の1つですルール。これはPython 3.0で修正されました。 [*]
しかし、Paoloが言うように、g.__next__()
を呼び出す代わりに、next(g)
を使用します。
[*]この修正を取得した他の特別な属性があります。 func_name
は、現在__name__
などです。
コードをPython2およびPython3で実行する必要がある場合は、次のように2to3 six ライブラリを使用します。
import six
six.next(g) # on PY2K: 'g.next()' and onPY3K: 'next(g)'