例外は、重要なプログラムでエラーを快適にルーティングして処理する方法です。しかし、明確な概念は、プログラムが大きくなったときにそれを無作為にハックしないようにするのに役立ちます。(たとえば、ビルトインを遠くで
キャッチしたり、たまたま ing / 続行したりすると、すぐに毛むくじゃらになります。)ValueError
return
発生したエラーには主な違いがあります
- 無効な/奇妙なユーザー入力による
- バグによる
- 動的なシステム/環境の制限によって。
これらのエラーを分離、ルーティング、および処理する合理的な方法は次のとおりです。
(A) ユーザー入力エラーが発生する可能性がある時点で非常に早い段階でキャッチまたは比較します。単純な回復/繰り返しの場合はすぐに反応します。それ以外の場合 (ブレイクアウト用)は、さらに下またはコール スタックの下部で (または既定のハンドラーによって)キャッチして区別できる強化された例外に変換します。sys.excepthook
(B) バグの例外をコール スタックの一番下にクラッシュさせます - 未処理。または、快適なバグ プレゼンテーションとフィードバック アクションを開始することもできます。
(C) システム環境エラーについては、開発の現在の段階でどの程度のコンテキスト、詳細、および快適な情報を提示するかに応じて、(A) と (B) のいずれかのアプローチを選択します。
このようにして、これはあなたの例でユーザー指向のエラー処理のスケーラブルなパターンになる可能性があります:
# Shows scalable user oriented error handling
import sys, traceback
DEBUG = 0
class UserInputError(Exception):
pass
def excercise5():
print("Programming Excercise 5")
print("This program calculates the cost of an order.")
# NOTE: eval() and input() was dangerous
s = input("Enter the weight in pounds: ")
try:
pound = float(s)
except ValueError as ev:
raise UserInputError("Number required for weight, not %r" % s, ev)
if pound < 0:
raise UserInputError("Positive weight required, not %r" % pound)
shippingCost = (0.86 * pound) + 1.50
coffee = (10.50 * pound) + shippingCost
if pound == 1:
print(pound,"pound of coffee costs $", coffee)
else:
print(pound,"pounds of coffee costs $", coffee)
print()
if __name__ == '__main__':
try:
excercise5()
except UserInputError as ev:
print("User input error (please retry):")
print(" ", ev.args[0])
if DEBUG and len(ev.args) > 1:
print(" EXC:", ev.args[1], file=sys.stderr)
except (EnvironmentError, KeyboardInterrupt) as ev:
print("Execution error happend:")
print(" ", traceback.format_exception_only(ev.__class__, ev)[0])
except Exception:
print("Please report this bug:")
traceback.print_exc()