5

ジェネレーターで発生する可能性のある例外をキャッチする必要がある場合、try ブロックをできるだけ小さく保つにはどうすればよいですか?

典型的な状況は次のようになります。

for i in g():
  process(i)

g()キャッチする必要がある例外を発生させることができる場合、最初のアプローチは次のとおりです。

try:
  for i in g():
    process(i)
except SomeException as e:
  pass  # handle exception ...

SomeExceptionしかし、これは発生した場合にもキャッチされますprocess(i)(これは私が望んでいないことです)。

この状況を処理するための標準的なアプローチはありますか? なんかのパターン?

私が探しているのは、次のようなものです。

try:

  for i in g():

except SomeException as e:
  pass  # handle exception ...

    process(i)

(もちろん、これは構文上のナンセンスです。)

4

4 に答える 4

3

内部ブロックで発生する例外を変換できます。

class InnerException(Exception):
  pass

try:
  for i in g():
    try:
      process(i)
    except Exception as ex:
      raise InnerException(ex)
except InnerException as ex:
  raise ex.args[0]
except SomeException as e:
  pass  # handle exception ...

別のオプションは、ラップするローカルジェネレーターを作成することですg

def safe_g():
  try:
    for i in g():
      yield i
  except SomeException as e:
    pass  # handle exception ...
for i in safe_g():
  process(i)
于 2012-11-23T13:48:17.573 に答える
2

これに対する直接的なアプローチは、構造をそのコンポーネントにアンラップすることのようですfor(これにより、その構文のために、ジェネレーターだけで例外をキャッチすることができなくなります)。

gen = g()
while True:
  try:
    i = gen.next()
  except StopIteration:
    break
  process(i)

tryこれで、予想される例外をブロックに追加できます。

gen = g()
while True:
  try:
    i = gen.next()
  except StopIteration:
    break
  except SomeException as e:
    pass  # handle exception ...
    break
  process(i)

それには(地獄のように醜いことに加えて)欠点がありますか?その他: より良い解決策はありますか?

(自分の答えは醜いので受け入れませんが、他の人が好きで賛成するかもしれません。)

于 2012-11-23T14:02:44.617 に答える
1

ジェネレーターで、区別できる別の種類の例外を発生させます。

class GeneratorError(Exception):
    pass

def g():
    try:
        yield <smth>
    except:
        raise GeneratorError

try:
  for i in g():
    process(i)
except GeneratorError:
    pass  # handle generator error
except SomeException as e:
  pass  # handle exception .
于 2012-11-23T13:42:31.490 に答える
0

それがうまくいくかどうかはわかりません。あなたはリストに評価g()することができます。手元に例外をスローするイテレータがないため、テストできません。

try:
    glist = list(g())
except SomeException as e:
    pass  # handle exception ...
for i in glist:
    process(i)
于 2012-11-23T13:52:54.413 に答える