これを複数回行う必要がある場合は、Hyperboreus と他の人が関数として提供した回答をまとめることができます。
def first_success(*callables):
for f in callables:
try:
return f()
except Exception as x:
print('{} failed due to {}'.format(f.__name__, x))
raise RuntimeError("still fail")
次に、必要なのは次のとおりです。
first_success(trial_1, trial_2, trial_3, trial_4)
logging.info
それらの代わりに例外が必要な場合print
、またはそれらを完全に無視する場合、またはそれらを追跡し、例外のリストを戻り値および/または例外に属性として添付するなどの場合、これを変更する方法はかなり明白なはずです.
関数に引数を渡したい場合、それはそれほど明白ではありませんが、それでも非常に簡単です。インターフェイスがどうあるべきかを決めるだけです。最初の引数として callable のシーケンスをとり、その後にすべての callable の引数をとります:
first_success((trial_1, trial_2, trial_3, trial_4), 42, spam='spam')
簡単だ:
def first_success(callables, *args, **kwargs):
for f in callables:
try:
return f(*args, **kwargs)
except Exception as x:
print('{} failed due to {}'.format(f.__name__, x))
else:
raise RuntimeError("still fail")
常にこのパターンが必要なわけではないが、まったく同じではないものがたくさん必要な場合は、代わりに、任意の関数をtry
. 私は実際にこれを6回構築しましたが、この関数を不要にするコードを書くためのよりpythonicな方法があることに気付きました。あなたはそれのより良い使い方を見つけるかもしれません:
def tried(callable, *args, **kwargs):
try:
return (callable(*args, **kwargs), None)
except Exception as x:
return (None, x)
、 などの高階関数を使用できるようmap
になりましany
た。たとえば、map(tried, (trial_1, trial_2, trial_3, trial_4))
4 つの非スロー関数のシーケンスを提供(f(x[0]) if x[1] is None else x for x in tried_sequence)
し、Python で Haskell モナド チュートリアルを実行できます。これは、両方の Python プログラマーを作成するための良い方法です。 Haskell プログラマーはあなたを嫌っています。