PyCharm IDEを使用する場合except:
、例外タイプなしでを使用すると、この例外句であるというIDEからの通知がトリガーされますToo broad
。
このアドバイスは無視すべきですか?それとも例外タイプを常に特定するのはPythonicですか?
PyCharm IDEを使用する場合except:
、例外タイプなしでを使用すると、この例外句であるというIDEからの通知がトリガーされますToo broad
。
このアドバイスは無視すべきですか?それとも例外タイプを常に特定するのはPythonicですか?
回答:
ほとんどの場合、明示的な例外タイプを指定することをお勧めします。裸のexcept:
句を使用すると、キャッチするはずの例外以外の例外がキャッチされる可能性があります。これにより、バグが非表示になったり、プログラムが期待どおりに動作していないときにプログラムのデバッグが困難になったりする可能性があります。
たとえば、データベースに行を挿入する場合、その行がすでに存在することを示す例外をキャッチして、更新を行うことができます。
try:
insert(connection, data)
except:
update(connection, data)
bareを指定するexcept:
と、データベースサーバーがフォールオーバーしたことを示すソケットエラーもキャッチされます。処理方法がわかっている例外のみをキャッチするのが最善です。多くの場合、プログラムは例外の時点で失敗する方が、続行するよりも奇妙な予期しない動作をするよりも優れています。
ベアを使用したい場合の1つexcept:
は、ネットワークサーバーのように、常に実行している必要があるプログラムの最上位レベルです。ただし、その場合は例外をログに記録するように細心の注意を払う必要があります。そうしないと、問題の原因を突き止めることができなくなります。基本的に、これを行うプログラム内の場所は1つだけです。
これすべての当然の結果は、raise Exception('some message')
クライアントコードを使用するように強制するためexcept:
(またはexcept Exception:
それとほぼ同じくらい悪いため)、コードが実行してはならないことです。通知したい問題に固有の例外を定義する必要があります(ValueError
またはなどの組み込みの例外サブクラスから継承している場合がありますTypeError
)。または、特定の組み込み例外を発生させる必要があります。これにより、コードのユーザーは、処理したい例外だけをキャッチすることに注意することができます。
except:
他の多くのものの中で)NameError
をキャッチAttributeError
し、try
ブロックのスペルを間違えた場合(たとえば、insert_one
誰かが必要以上に一貫性を評価しなかったために「挿入」関数が実際に呼び出された場合)、常に静かにしようとしupdate()
ます。
main()
)?
except Exception:
キャッチしますNameError
とAttributeError
、あまりにも。むずかしいのexcept:
は、ビジネスがキャッチされていないものをキャッチすることです。たとえば、SystemExit
(exit
またはを呼び出すsys.exit
と発生し、意図したexitが阻止されます)、KeyboardInterrupt
(ここでも、ユーザーがCtrl-C
を押した場合、おそらく必要ありません)それらを悪用するだけのために実行し続けるため)。後者だけがキャッチしても意味があり、明示的にキャッチする必要があります。少なくともexcept Exception:
これら2つは正常に伝播します。
通訳からのアドバイスを無視してはいけません。
Python のPEP-8スタイルガイドから:
例外をキャッチするときは、裸のexcept:句を使用するのではなく、可能な限り特定の例外に言及してください。
たとえば、次のように使用します。
try:
import platform_specific_module
except ImportError:
platform_specific_module = None
ベアのexcept:句はSystemExitおよびKeyboardInterrupt例外をキャッチし、Control-Cでプログラムを中断することを困難にし、他の問題を偽装することができます。プログラムエラーを通知するすべての例外をキャッチする場合は、except Exception:を使用します(bare exceptはexcept BaseException:と同等です)。
大まかな経験則として、裸の「except」句の使用を2つのケースに制限します。
例外ハンドラがトレースバックを出力またはログする場合。少なくともユーザーはエラーが発生したことに気づくでしょう。コードでクリーンアップ作業を行う必要があるが、レイズで例外を上方に伝播させる場合。試してみてください...最終的には、このケースを処理するためのより良い方法です。
Pythonに固有ではありません。
例外の全体的なポイントは、問題が発生した場所のできるだけ近くで問題に対処することです。
したがって、例外的な状況で問題が発生し、解決策が互いに「隣り合う」可能性があるコードを保持します。
問題は、コードによってスローされる可能性のあるすべての例外を知ることができないことです。あなたが知ることができるのは、たとえばファイルが見つからないという例外であれば、それをトラップして、ユーザーに機能を実行するかキャンセルするように促すことができるということだけです。
あなたがそれを試してみると、ファイルルーチンにどんな問題があったとしても(読み取り専用、権限、UAC、実際にはpdfなどではない)、すべての人があなたのファイルを見つけられませんでした。 「しかし、そこにある、このコードはくだらない」と叫んでいる
今、あなたはすべてを捕まえるかもしれない状況がいくつかありますが、それらは意識的に選ばれるべきです。
それらはキャッチであり、いくつかのローカルアクション(リソースの作成またはロックなど)(ディスク上でファイルを開いて書き込むなど)を取り消し、次に例外を再度スローして、より高いレベルで処理されます)
もう1つは、問題が発生した理由を気にしないことです。たとえば印刷。プリンタに問題があります。問題を解決するためにアプリケーションを強制終了しないでください。同様に、コードがなんらかのスケジュールを使用して一連の個別のタスクを実行した場合、タスクの1つが失敗したため、すべてを終了させたくはありません。
注上記を行う場合、ある種の例外ログをお勧めすることはできません。たとえば、catch log endを十分に試してください。
また、たとえばControl-Cをキャッチすることになるので、もう一度「スロー」しない限り、それを行わないでください。ただし、その場合は「最終的に」を使用する必要があります。
常にあなたのような、キャッチしたくない多くの種類があり、例外の型を指定しSyntaxError
、KeyboardInterrupt
、MemoryError
など
except Exception:
たくない上記のタイプを使用しないでください?
except Exception
結構です。
except Exception
キャッチSyntaxError
しMemoryError
、それが基本クラスであるため。KeyboardInterrupt
、SystemExit
(によって発生sys.exit()
)はキャッチされません(これらは即時のBaseExceptionサブクラスです)
タイプなしで使用する場合を除いて、私が使用する場所は次のとおりです
それは私のコードでチェックされていない例外の主な用途です
私は常にこれを追加して、量産コードがスタックトレースをこぼさないようにします
私にはそれを行う2つの方法があります。
私はこの方法を好みます。どの例外が適切にキャッチされるべきかを検出する方が簡単だと思います。より低いレベルの例外がより高いレベルでログに記録されると、問題をよりよく「見る」ことができます
一部の同僚は、「所属」する下位レベルの関数で下位レベルの例外を保持するため、この方法を好みます。