2013-01-06 6 views
21

私は、発電機でraise StopIterationreturnのステートメントを使用する違いについて興味があります。発電機のStopIterationとreturnステートメントの違いは何ですか?

たとえば、これらの2つの機能に違いはありますか?私はそれを行うには、より「神託」道を推測している

def my_generator0(n): 
    for i in range(n): 
     yield i 
     if i >= 5: 
      return 

def my_generator1(n): 
    for i in range(n): 
     yield i 
     if i >= 5: 
      raise StopIteration 

は(私が間違っている場合は、私を修正してください)第二の方法ですが、私の知る限り、両方の方法はStopIteration例外を発生させます。

+2

明示的または暗黙的な( '末端オフ') 'return'は、発電を停止することを意図するものである方法。 PEP 479が承認された場合、 'raise StopIteration'バージョンは最終的には機能しません。 –

答えて

28

StopIterationを明示的に呼び出す必要はありません。これは、裸のreturn文がジェネレータ関数に対して実行するものであるため、同じです。しかし、いいえ、ちょうどreturnを使うのはPythonicです。

から:ジェネレータ関数でhttp://docs.python.org/2/reference/simple_stmts.html#the-return-statement(Pythonの3.2への有効)

、return文は、expression_listを含めることはできません。このコンテキストでは、裸のリターンは、ジェネレータが完了し、StopIterationが発生することを示します。

それとも@Bakuriuが指摘するように - 発電機のセマンティクスは、Python 3.3のために、わずかに変更されているので、以下では、より適切です:

ジェネレータ関数では、return文は、発電機があることを示し、 stopIterationが呼び出されます。戻り値(存在する場合)は、StopIterationを構築するための引数として使用され、StopIteration.value属性になります。

+3

python3では、returnには式リストの引数があります:http://docs.python.org/3.3/reference/simple_stmts.html#the-return-statement – Bakuriu

3

これは当てはまりますが、一方は読みやすく、他方はあいまいであることを除いて同等です。これはジェネレータの最初のバージョン(PEP 255、 "仕様:リターン")にまでさかのぼり、その後の強化(コルーチンなど)はこれを変更しません。 3.3のyield from(PEP 380)は、raise StopIteration(<expr>)の構文糖としてそれをreturn <expr>に拡張しますが、それはreturn;という意味を変更しません。

12

2014年末現在returnが正しく、ジェネレータを終了するためのraise StopIterationは減価償却スケジュールになっています。詳細はPEP 479を参照してください。

このPEP抽象

は、発電機への変更を提案している:StopIterationは、発電機の内部で発生したとき、それはRuntimeErrorに置き換えられています。 (より正確には、例外はジェネレータのスタックフレームから例外がバブルアウトしようとしているときに発生します。)変更は後方互換性がないため、機能は最初に__future__ステートメントを使用して導入されます。

受け入れ

このPEPは、11月22日BDFLに受け入れられた...

理由

発電機との相互作用を呼び出すとStopIterationは現在、やや驚くべきことである、とあいまいなバグを隠すことができます。予期しない例外が微妙な動作の変更を引き起こしてはいけませんが、ノイズの多い簡単にデバッグされたトレースバックが発生するはずです。現在、ジェネレータ関数内で誤って発生したStopIterationは、ジェネレータを駆動するループコンストラクトによる反復の終了として解釈されます。

...

関連する問題