ターゲット関数で発生したエラーをキャッチし、ユーザーがスクリプトの実行を続行する (関数をバイパスする) か、スクリプトからドロップアウトできるようにするデコレータを作成しています。
def catch_error(func):
"""
This decorator is used to make sure that if a decorated function breaks
in the execution of a script, the script doesn't automatically crash.
Instead, it gives you the choice to continue or gracefully exit.
"""
def caught(*args):
try:
return func(*args)
except Exception as err:
question = '\n{0} failed. Continue? (yes/no): '.format(func.func_name)
answer = raw_input(question)
if answer.lower() in ['yes','y']:
pass
else:
print " Aborting! Error that caused failure:\n"
raise err
return None
return caught
ユーザーがエラーを返す関数をバイパスしてスクリプトの実行を続行することを選択した場合、デコレータは None を返すことに注意してください。これは、単一の値のみを返す関数ではうまく機能しますが、複数の値をアンパックしようとする関数ではクラッシュします。例えば、
# Both function and decorator return single value, so works fine
one_val = decorator_works_for_this_func()
# Function nominally returns two values, but decorator only one, so this breaks script
one_val, two_val = decorator_doesnt_work_for_this_func()
ターゲット関数が返す値の数を特定する方法はありますか? たとえば、次のようなものです。
def better_catch_error(func):
def caught(*args):
try:
return func(*args)
except Exception as err:
...
num_rvals = determine_num_rvals(func)
if num_rvals > 1:
return [ None for count in range(num_rvals) ]
else:
return None
return caught
いつものように、この種のことを行うためのより良い方法があれば、私に知らせてください. ありがとう!
アップデート:
すべての提案をありがとう。私は、catch_error の範囲を、1 つの文字列値のみを返す単一クラスの関数に絞り込むことにしました。複数の値を返すすべての関数を、単一の値を返す個別の関数に分割して、互換性を持たせました。私は catch_error をより一般的なものにしたいと考えていました (そして、その方法についていくつかの役立つ提案がありました) が、私のアプリケーションにとっては少しやり過ぎでした。再度、感謝します。