4

私はしばしば、いくつかのコレクションを反復処理し、要素を処理して結果を生成するジェネレーターを持っています。要素の処理で例外が発生する場合があります。ジェネレーターを終了せずに、ジェネレーターの呼び出し元でそのようなジェネレーターで発生するそのような例外を処理したいと思います。結局、反復ではなく処理だけが失敗したため、ジェネレーターは次の反復要素を続行できました。状況を表示する例:

def generator():
  for element in collection:
    yield process(element)  # might raise Exception

def caller():
  for product in generator():
    doSomethingWith(product)

process()でスローされた例外を処理したいと思いcaller()ます。残念ながら、 で例外process()が発生しgenerator()、ジェネレーターが終了します (ここでもっと複雑なことをしなければ)。したがって、素朴なアプローチは失敗します。

def generator():
  for element in collection:
    yield process(element)  # might raise Exception

def caller():
  for product in generator():
    try:   # wrong place for try, as the loop will already fail
      doSomethingWith(product)
    except Exception as problem:
      handleProblem(problem)

現在、私の作業中の欠陥のあるアプローチは、例外を生成された値として渡すことです。

def generator():
  for element in collection:
    try:
      yield process(element)  # might raise Exception
    except Exception as problem:
      yield problem

def caller():
  for yielded in generator():
    if isinstance(yielded, Exception):
      problem = yielded
      handleProblem(problem)
    else:
      product = yielded
      doSomethingWith(product)

これは機能しますが、次のようないくつかの欠点があります

  • これは、製品と例外を区別できるという事実に依存します (通常は例外を生成するジェネレーターでは機能しません)。もちろん、ラッピングを使用してそれを解決できます。
  • 生成された値 ( ) を受け取った直後に、醜いチェック パターンが必要ですif isinstance(...)
  • 通常の Python 例外処理を使用しないため、例外の再発生などによって問題が発生する可能性があります (完全にはチェックしていません)。

これに関するより良いアプローチはありますか?特定の例外のみをキャッチする(他の例外をキャッチしない)などの柔軟性を提供するため、使用する代わりに例外を処理するためにtry/exceptパターンを使用することをお勧めします。caller()if

4

0 に答える 0