web-dev-qa-db-ja.com

Raise TryとAssertの違い

私はしばらくの間、Pythonとraise関数とassertが学習していました(私が気づいたのは、トライとは異なり、どちらもアプリをクラッシュさせることです-例外)本当に似ており、raiseを介してassertまたはtryを使用する状況は見当たりません。

では、Raise、Try、およびAssertの違いは何ですか?

21
Defneit

アサート:

特定の条件に基づいてスクリプトを「停止」し、デバッグを高速化するために何かを返す場合に使用します。

_list_ = ["a","b","x"]
assert "x" in list_, "x is not in the list"
print("passed") 
#>> prints passed

list_ = ["a","b","c"]
assert "x" in list_, "x is not in the list"
print("passed")
#>> 
Traceback (most recent call last):
  File "python", line 2, in <module>
AssertionError: x is not in the list
_

上げる:

これに役立つ2つの理由:

1/tryブロックおよびexceptブロックで使用されます。選択したエラーが発生します。以下のようにカスタムにすることができ、スクリプトをpassまたはcontiuneした場合、スクリプトを停止しません。または、事前定義されたエラーraise ValueError()

_class Custom_error(BaseException):
    pass

try:
    print("hello")
    raise Custom_error
    print("world")
except Custom_error:
    print("found it not stopping now")

print("im outside")

>> hello
>> found it not stopping now
>> im outside
_

止まらないことに気付いた? exceptブロックで単にexit(1)を使用して停止できます。

2/Raiseは、現在のエラーを再発生させてスタックに渡して、他の何かがそれを処理できるかどうかを確認するためにも使用できます。

_except SomeError, e:
     if not can_handle(e):
          raise
     someone_take_care_of_it(e)
_

ブロックを試す/除外する:

あなたが考えていることを正確に行い、何かを試みます。エラーが発生した場合、あなたはそれをキャッチし、あなたが好きなように対処します。上記のものがあるので、例はありません。

27
MooingRawr
assert cond, "text"

のようなものに展開されます

if cond == False:
  raise AssertionError("text")

読みやすいのでアサートを使用します。

26
Michal Krzyz

raise-例外を発生させます。

assert-例外を発生させますif指定された条件がtrue(またはtrueではない)です。

try-might例外を発生させるコードを実行し、そうであればキャッチします。

18
John Gordon

try/exceptブロックを使用すると、例外をキャッチして管理できます。例外は、raiseassert、および空のリストにインデックスを付けようとするなどの多数のエラーによってトリガーされます。 raiseは通常、エラー状態を検出したときに使用されます。 assertも同様ですが、例外は条件が満たされた場合にのみ発生します。

raiseassertの哲学は異なります。エラーを検出して発生させるコードには、多くの「通常の」エラーがあります。おそらく、Webサイトが存在しないか、パラメーター値が範囲外です。

アサーションは通常、とにかく起こると思われる「これは起こらないと誓います」問題のために予約されています。通常のランタイムエラー検出よりも、ランタイムデバッグに似ています。アサーションは、-Oフラグを使用する場合、または.pyoファイルの代わりに.pycファイルから実行する場合は無効にできるため、通常のエラー検出の一部ではありません。

製品品質のコードで例外が発生する場合は、何が間違っていたかを把握してください。 AssertionErrorが発生する場合、より大きな問題があります。

10
tdelaney

通常、アサートはコードをテストするために使用され、何かが機能することを確認します。

def test_bool():
    assert True != False

pythonでエラーを処理および伝播するための好ましい方法であるメークアップ例外処理を発生させ、除外する場合。

ほとんどのライブラリとpythonビルトインは、何かがうまくいかない場合、何らかのタイプの例外を発生させます。多くの場合、自分のコードでは、何か問題が発生したことを検出したときに例外を発生させます例として、メールアドレスバリデータを書いていて、アドレスに@記号が含まれていなかった場合に例外を発生させたいとしましょう。次のようなものがあります(これはおもちゃのコードです。実際にこのようなメールを検証しないでください。 ):

def validate_email(address):
    if not "@" in address:
        raise ValueError("Email Addresses must contain @ sign")

その後、コードの別の場所でvalidate_email関数を呼び出すことができ、失敗すると例外がスローされます。

try:
    validate_email("Mynameisjoe.com")
except ValueError as ex:
    print("We can do some special invalid input handling here, Like ask the user to retry the input")
finally:
    close_my_connection()
    print("Finally always runs whether we succeed or not. Good for clean up like shutting things down.")

知っておくべき重要なことは、例外が発生すると、ハンドラーが見つかるまで呼び出しスタックに渡されることです。ハンドラが見つからない場合は、例外とスタックトレースでプログラムがクラッシュします。

したくないことの1つは、次のようなものです。

if __name__ == '__main__':
    try:
        print(1/0)
    except Exception as ex:
        pass

これで、アプリケーションが爆発した理由を知る方法がなくなりました。

よく目にすることの1つは、次のようなものです。

import logging
if __name__ == '__main__':
    try:
        print(1/0)
    except Exception as ex:
        logging.exception(ex)
        raise

パラメータがないため、この場合のレイズは同じエラーを再発生させます。多くの場合、Webコードでは、クライアントに500エラーを送信してから次のリクエストを続行するため、例外を再発生させない同様の何かが表示されます。その場合、プログラムを終了させたくありません。

1

例外は、Python(および他のいくつかの言語)がコードの実行時に発生するエラーに対処するために使用するものです。raise ExceptionNameは、コードにエラーがあると言っており、その問題に関連する例外を発生させることにより、それがどのような問題であるかを特定しています。 assert expressionexpressionを評価し、falseの場合は例外を発生させます。

tryは、期待する例外を発生させる可能性のあるコードを実行するために使用されます。プログラムを停止する代わりに、例外を「キャッチ」してコードで処理できます。

例:辞書とリストがあるとしましょう。辞書にないものに到達するまで、辞書のリストから物事を見たい:

try:
    for item in my_list:
        print(my_dictionary[item])
except KeyError as e: #KeyError is the Exception raised when a key is not in a dictionary
    print('There is no {} in the dictionary'.format(e.args[0]))
1
Patrick Haugh

assertraise AssertionErrorに違いはありません。まったく同じバイトコードにコンパイルされます。

import dis

def foo1(param):
    assert param, "fail"

def foo2(param):
    if not param:
        raise AssertionError("fail")

print(dis.dis(foo1))
print(dis.dis(foo2))

出力:

 4           0 LOAD_FAST                0 (param)
             2 POP_JUMP_IF_TRUE        12
             4 LOAD_GLOBAL              0 (AssertionError)
             6 LOAD_CONST               1 ('fail')
             8 CALL_FUNCTION            1
            10 RAISE_VARARGS            1
       >>   12 LOAD_CONST               0 (None)
            14 RETURN_VALUE
None
 7           0 LOAD_FAST                0 (param)
             2 POP_JUMP_IF_TRUE        12

 8           4 LOAD_GLOBAL              0 (AssertionError)
             6 LOAD_CONST               1 ('fail')
             8 CALL_FUNCTION            1
            10 RAISE_VARARGS            1
       >>   12 LOAD_CONST               0 (None)
            14 RETURN_VALUE
None
0
ruohola