[解決済み] Pythonで例外を手動で発生(スロー)させる
質問
Pythonで例外を発生させ、その例外を後で
except
ブロックは?
どのように解決するのですか?
<ブロッククオートPythonで例外を手動で投げる/発生させる方法は?
あなたの問題にセマンティックにフィットする最も具体的なExceptionコンストラクタを使用します。 .
メッセージは具体的に、例えば以下のように。
raise ValueError('A very specific bad thing happened.')
汎用的な例外を発生させない
を発生させないようにします。
Exception
. この例外をキャッチするためには、この例外をサブクラスとする他のより具体的な例外をすべてキャッチしなければならなくなります。
問題点1:バグの隠蔽
raise Exception('I know Python!') # Don't! If you catch, likely to hide bugs.
例えば
def demo_bad_catch():
try:
raise ValueError('Represents a hidden bug, do not catch this')
raise Exception('This is the exception you expect to handle')
except Exception as error:
print('Caught this error: ' + repr(error))
>>> demo_bad_catch()
Caught this error: ValueError('Represents a hidden bug, do not catch this',)
問題2: キャッチできない
また、より具体的なキャッチは、一般的な例外をキャッチしません。
def demo_no_catch():
try:
raise Exception('general exceptions not caught by specific handling')
except ValueError as e:
print('we will not catch exception: Exception')
>>> demo_no_catch()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in demo_no_catch
Exception: general exceptions not caught by specific handling
ベストプラクティス
raise
ステートメント
その代わりに、あなたの問題にセマンティックに適合する最も具体的なExceptionコンストラクタを使用します。 .
raise ValueError('A very specific bad thing happened')
また、コンストラクタに渡す引数の数を任意に設定できるのも便利です。
raise ValueError('A very specific bad thing happened', 'foo', 'bar', 'baz')
これらの引数へのアクセスは
args
属性は
Exception
オブジェクトを作成します。例えば
try:
some_code_that_may_raise_our_value_error()
except ValueError as err:
print(err.args)
印刷物
('message', 'foo', 'bar', 'baz')
Python 2.5では、実際の
message
属性が追加され
BaseException
を使わないで、Exceptionをサブクラス化することを推奨しています。
args
しかし
の導入は
message
と、当初非推奨だったargsが撤回されました。
.
ベストプラクティス
except
条項
except節内では、例えば、特定のタイプのエラーが発生したことを記録し、その後、再レイズしたい場合があります。スタックトレースを維持しながらこれを行う最良の方法は、素の raise 文を使用することです。例えば
logger = logging.getLogger(__name__)
try:
do_something_in_app_that_breaks_easily()
except AppError as error:
logger.error(error)
raise # just this!
# raise AppError # Don't do this, you'll lose the stack trace!
エラーを修正しないで...どうしてもと言うなら。
でスタックトレース(とエラー値)を保持することができます。
sys.exc_info()
しかし
これは、よりエラーが発生しやすい
そして
は、Python 2 と 3 の間の互換性に問題があります。
を使用することを好みます。
raise
をリレイズしてください。
説明すると、-は
sys.exc_info()
は、型、値、トレースバックを返します。
type, value, traceback = sys.exc_info()
これはPython 2の構文です - Python 3とは互換性がないことに注意してください。
raise AppError, error, sys.exc_info()[2] # avoid this.
# Equivalently, as error *is* the second object:
raise sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]
もし必要なら、新しいレイズで起こることを変更することができます - たとえば、新しい
args
をインスタンスに追加します。
def error():
raise ValueError('oops!')
def catch_error_modify_message():
try:
error()
except ValueError:
error_type, error_instance, traceback = sys.exc_info()
error_instance.args = (error_instance.args[0] + ' <modification>',)
raise error_type, error_instance, traceback
そして、引数を変更しながら、全体のトレースバックを保存しています。なお、これは ベストプラクティスではありません であり、それは 無効な構文 は、Python 3では、互換性を維持することが非常に難しくなっています。
>>> catch_error_modify_message()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in catch_error_modify_message
File "<stdin>", line 2, in error
ValueError: oops! <modification>
で パイソン3 :
raise error.with_traceback(sys.exc_info()[2])
繰り返しになりますが、トレースバックを手動で操作するのは避けてください。それは
効率が悪い
とエラーが発生しやすくなります。また、スレッディングを使用している場合や
sys.exc_info
特に、制御フローに例外処理を使用している場合は、個人的には避けたいところです)。
Python 3, 例外連鎖
Python 3 では、トレースバックを保持するために例外を連結することができます。
raise RuntimeError('specific message') from error
意識してください。
- これ が行います。 発生したエラーの種類を変更できるようにし
- これは ない Python 2 と互換性があります。
非推奨のメソッド
これらは簡単に隠れることができ、プロダクションコードに入り込むことさえあります。例外を発生させたいのに、それらをやると例外が発生します。 が、意図したものではありません!
Python 2 では有効だが、Python 3 では無効である。 は以下の通りです。
raise ValueError, 'message' # Don't do this, it's deprecated!
のみ Pythonのかなり古いバージョンで有効 (2.4以下)の場合、まだ文字列を上げる人を見かけるかもしれません。
raise 'message' # really really wrong. don't do this.
すべての最新バージョンでは、これは実際に
TypeError
を発生させているわけではありませんから。
BaseException
という型があります。正しい例外をチェックせず、問題を認識しているレビュアーがいなければ、生産に支障をきたす可能性があります。
使用例
自分のAPIの利用者が間違った使い方をした場合に、Exceptionを発生させて警告を出す。
def api_func(foo):
'''foo should be either 'baz' or 'bar'. returns something very useful.'''
if foo not in _ALLOWED_ARGS:
raise ValueError('{foo} wrong, use "baz" or "bar"'.format(foo=repr(foo)))
必要に応じて、独自のエラータイプを作成する
<ブロッククオートexcept"に入るように、わざとエラーを出したいのですが。
アプリケーションに何か問題があることを示したい場合は、例外階層の適切な箇所をサブクラス化するだけで、独自のエラータイプを作成することができます。
class MyAppLookupError(LookupError):
'''raise this when there's a lookup error for my app'''
と使用方法を説明します。
if important_key not in resource_dict and not ok_to_be_missing:
raise MyAppLookupError('resource is missing, and that is not ok.')
関連
-
任意波形を生成してtxtで保存するためのPython実装
-
[解決済み】syntaxError: 'continue' がループ内で適切に使用されていない
-
[解決済み] 関数デコレータを作成し、それらを連鎖させるには?
-
[解決済み] 複数の例外を一度にキャッチする?
-
[解決済み] JUnit 4のテストで、ある例外が投げられたことをどのように断言しますか?
-
[解決済み] 最近のPythonでカスタム例外を宣言する適切な方法?
-
[解決済み] Pythonで例外を表示するには?
-
[解決済み】forループを使った辞書の反復処理
-
[解決済み】Pythonに三項条件演算子はありますか?
-
[解決済み】2つの辞書を1つの式でマージする(辞書の和をとる)には?)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
PicgoのイメージベッドツールをPythonで実装する
-
Python LeNetネットワークの説明とpytorchでの実装
-
[解決済み】DataFrameのコンストラクタが正しく呼び出されない!エラー
-
[解決済み] _tkinter.TclError: 表示名がなく、$DISPLAY環境変数もない。
-
[解決済み】Python regex AttributeError: 'NoneType' オブジェクトに 'group' 属性がない。
-
[解決済み] データ型が理解できない
-
[解決済み】csv.Error:イテレータはバイトではなく文字列を返すべき
-
[解決済み】syntaxError: 'continue' がループ内で適切に使用されていない
-
[解決済み】Python elifの構文が無効です【終了しました
-
[解決済み】Pythonで "raise "キーワードを使用する方法【重複あり