Python 3でgenerator.next()は表示されますか?


247

たとえば、シリーズを生成するジェネレータがあります。

def triangle_nums():
    '''Generates a series of triangle numbers'''
    tn = 0
    counter = 1
    while True:
        tn += counter
        yield tn
        counter += + 1

Python 2では、次の呼び出しを行うことができます。

g = triangle_nums()  # get the generator
g.next()             # get the next value

ただし、Python 3で同じ2行のコードを実行すると、次のエラーが発生します。

AttributeError: 'generator' object has no attribute 'next'

しかし、ループ反復子構文はPython 3では機能します

for n in triangle_nums():
    if not exit_cond:
       do_something()...

このPython 3の動作の違いを説明するものはまだ見つかりません。

回答:


406

g.next()に名前が変更されましたg.__next__()。これの理由は一貫性です。__init__()およびのような特別なメソッドは__del__()すべて2つのアンダースコア(または現在の専門用語では "dunder")を持ち.next()、そのルールのいくつかの例外の1つでした。これはPython 3.0で修正されました。[*]

ただし、ではなくをg.__next__()使用しますnext(g)

[*]この修正を受けた他の特別な属性があります。func_name、今ある__name__など


なぜpython 2がそもそもこれらのメソッドのdunder規約を避けたのでしょうか?
Rickがモニカをサポートする

それはおそらく見落としです。
Lennart Regebro 2016年

クラスで__ str __を上書きする場合はどうですか?str(obj)または__str __(obj)を変更しますか?
-NoName、

@NoNameのようなものはない__str__(obj)ので、質問がよくわかりません。
Lennart Regebro

1
@NoNameはい、そうです。
Lennart Regebro

144

試してください:

next(g)

これに関しては、2と3の構文の違いを示したこのきちんとした表を確認してください。


1
@MaikuMoriリンクを修正しました(ピアの修正を待っています)(サイトdiveintopython3.orgはダウンしているようです。ミラーサイトdiveintopython3.ep.ioはまだ稼働しています)
gecco

1
リンクを再度修正しました。ところで、python3porting.com / differences.htmlはより完全です。
Lennart Regebro 2013

関数の方法からスイッチの任意の正当性がある、beyondがg.next()本当にあるべきg.__next__()、と私たちはの機能を持つdunder方法ではない何かを持っている必要がありますかg.next()
TCプロクター

11

コードをPython2およびPython3で実行する必要がある場合は、次のように2to3 6ライブラリを使用します。

import six

six.next(g)  # on PY2K: 'g.next()' and onPY3K: 'next(g)'

18
2.6より前のバージョンのPythonをサポートする必要がない限り、これはそれほど必要ありません。Python 2.6および2.7にはnext組み込み関数があります。
Mark Dickinson、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.