この質問は、ジェネレーター内のエラーをキャッチしてから続き、その後続行します
Web サイトから URL などを抽出しようとする約 50 の同様の (ただし異なる) 関数があります。Web サイトはそれぞれ異なり、それぞれの機能も異なります。また、Web サイトは時間の経過とともに変化する傾向があるため、このコードは乱雑で信頼できません。
これは単純化されたサンプルです。または、最初の質問のサンプルを見てください。
def _get_units(self):
for list1 in self.get_list1():
for list2 in self.get_list2(list1):
for unit in list2:
yield unit
この関数でやりたいことは、基本的にこれに合わせて動作を変更することです。
def _get_units(self):
for list1 in self.get_list1():
try:
for list2 in self.get_list2(list1):
try:
for unit in list2:
try:
yield unit
except Exception as e:
log_exception(e)
except Exception as e:
log_exception(e)
except Exception as e:
log_exception(e)
要するに、これを回したい
for x in list:
do_stuff(x)
これに:
for x in list:
try:
do_stuff(x)
except Exception as e:
log_exception(e)
for
私の機能のそれぞれについて。
しかし、私はpythonicな方法でそれをやりたいです。try:except
変更する必要がある 50 の関数全体にブロックが散在するのは望ましくありません。これは可能ですか?もしそうなら、どうすれば最もDRYな方法でそれを行うことができますか?また、エラー処理を1か所で行うことはできますか?
更新:この質問には、以前continue
はログと共にステートメントが含まれていましたが、mgilson が指摘したように、これは必要ありません。
UPDATE 2のgeorgeslの回答により、関数は次のようになります。
from contextlib import contextmanager
@contextmanager
def ErrorManaged():
try:
yield
except Exception as e:
log_exception(e)
def _get_units(self):
for list1 in self.get_list1():
with ErrorManaged():
for list2 in self.get_list2(list1):
with ErrorManaged():
for unit in list2:
with ErrorManaged():
yield unit
これは確かにずっときれいです。ただし、単なるデコレータの方がさらに優れています。これが可能かどうか誰にも教えてもらえますか? そうでない場合は、georgesl の回答を受け入れます。