web-dev-qa-db-ja.com

Pythonでの "assert"の使い方は何ですか?

私はいくつかのソースコードを読んでいて、いくつかの場所で私はassertの使い方を見ました。

それは正確にはどういう意味ですか?使い方は?

776
Hossein

assertステートメントは、ほとんどすべてのプログラミング言語に存在します。他の操作の副作用としてではなく、プログラムの早い段階(原因が明らかな場合)で問題を検出するのに役立ちます。

あなたがするとき...

assert condition

...その条件をテストし、条件が偽の場合は直ちにエラーを引き起こすようにプログラムに指示しています。

Pythonでは、これとほぼ同じです。

if not condition:
    raise AssertionError()

Pythonシェルで試してください。

>>> assert True # nothing happens
>>> assert False
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError

アサーションにはオプションのメッセージを含めることができ、インタープリタを実行するときにそれらを無効にすることができます。

アサーションが失敗した場合にメッセージを出力するには

assert False, "Oh no! This assertion failed!"

関数のようにassertを呼び出すには、notを括弧を使用してください。それは声明です。あなたがassert(condition, message)をするならば、あなたは最初のパラメータとして(condition, message) Tupleでassertを実行するでしょう。

それらを無効にすることに関して、最適化モードでpythonを実行するとき(__debug__False)には、assertステートメントは無視されます。 -Oフラグを渡すだけです:

python -O script.py

関連文書については ここ を参照してください。

879
slezica

括弧には気を付けてください。上で指摘したように、 Python 3では、assertはまだステートメントです 従って、print(..)と同じように、assert(..)またはraise(..)に同じことを外挿することができますが、そうしないでください。

これは重要です。

assert(2 + 2 == 5, "Houston we've got a problem")

とは異なり、動作しません

assert 2 + 2 == 5, "Houston we've got a problem"

最初のものが機能しないのは、bool( (False, "Houston we've got a problem") )Trueに評価されるからです。

ステートメントassert(False)では、これらはFalseを囲む単なる冗長な括弧です。しかしassert(False,)では括弧はTupleになり、空でないTupleはブール値のコンテキストでTrueと評価されます。

358
Evgeni Sergeev

他の回答が指摘しているように、assertは、特定の条件が真でない場合に例外をスローすることに似ています。重要な違いは、最適化オプションを使用してコードをコンパイルすると、assertステートメントが無視されることです。 documentation は、assert expressionが次と同等であると記述できることを示しています。

if __debug__:
   if not expression: raise AssertionError

これは、コードを徹底的にテストし、アサーションケースのいずれも失敗しないことに満足しているときに最適化バージョンをリリースする場合に役立ちます。最適化がオンになると、__debug__変数がFalseになり、条件が停止します評価される。この機能は、アサートに依存していて、それらが消滅したことに気付かない場合にも、あなたを見つけることができます。

123
Neil Vass

他の人たちはすでにあなたにドキュメンテーションへのリンクを与えています。

対話型のシェルで次のことを試すことができます。

>>> assert 5 > 2
>>> assert 2 > 5
Traceback (most recent call last):
  File "<string>", line 1, in <fragment>
builtins.AssertionError:

最初のステートメントは何もしませんが、2番目のステートメントは例外を発生させます。これが最初のヒントです。アサーションは、コードの特定の位置(通常、関数の始まり(前提条件)と終わり(postcondition))に当てはまる条件をチェックするのに役立ちます。

アサーションは実際には契約によるプログラミングと密接に関係しています。これは非常に便利なエンジニアリング手法です。

http://en.wikipedia.org/wiki/Design_by_contract

48
Baltasarq

Pythonでのアサーションの目的は、プログラムの回復不能エラーについて開発者に知らせることです。

アサーションは、「ファイルが見つかりません」など、ユーザーが修正アクションを実行できる(または単に再試行できる)予想されるエラー状態を通知することを目的としていません。

別の見方をすると、アサーションは内部セルフチェックであると言うことです。コード内でimpossibleとしていくつかの条件を宣言することで機能します。これらの条件が満たされない場合は、プログラムにバグがあることを意味します。

プログラムにバグがない場合、これらの状態は発生しません。ただし、それらのいずれかdoesが発生すると、プログラムはアサーションエラーでクラッシュし、どの「不可能な」条件がトリガーされたかを正確に示します。これにより、プログラムのバグを簡単に追跡して修正できます。

Pythonのアサーションに関するチュートリアル からの要約は次のとおりです。

Pythonのassert文はデバッグの補助であり、実行時エラーを処理するメカニズムではありません。アサーションを使用する目的は、開発者がバグの根本的な原因をより迅速に発見できるようにすることです。プログラムにバグがない限り、アサーションエラーは発生しません。

38
dbader

Assert文には2つの形式があります。

単純な形式assert <expression>は、次のものと同等です。

if __​debug__:
    if not <expression>: raise AssertionError

拡張形式のassert <expression1>, <expression2>は、次のものと同等です。

if __​debug__:
    if not <expression1>: raise AssertionError, <expression2>
17
Bohdan

アサーションは、バグを捉えることを目的として、プログラムの内部状態がプログラマの期待どおりであることを体系的にチェックする方法です。下記の例をご覧ください。

>>> number = input('Enter a positive number:')
Enter a positive number:-1
>>> assert (number > 0), 'Only positive numbers are allowed!'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: Only positive numbers are allowed!
>>> 
14
Jacob Abraham

ドキュメントから:

Assert statements are a convenient way to insert debugging assertions into a program

ここでもっと読むことができます: http://docs.python.org/release/2.5.2/ref/assert.html

12
gruszczy

これはファイルに保存する簡単な例です(b.pyとしましょう)。

def chkassert(num):
    assert type(num) == int


chkassert('a')

$python b.pyの場合の結果

Traceback (most recent call last):
  File "b.py", line 5, in <module>
    chkassert('a')
  File "b.py", line 2, in chkassert
    assert type(num) == int
AssertionError
7
Gaurav Agarwal

assertの後のステートメントが真であればプログラムは続行しますが、assertの後のステートメントが偽であればプログラムはエラーを出します。そのような単純な。

例えば。:

assert 1>0   #normal execution
assert 0>1   #Traceback (most recent call last):
             #File "<pyshell#11>", line 1, in <module>
             #assert 0>1
             #AssertionError
6
abe312

C2 Wiki :で簡潔に要約されているように

アサーションは、プログラム内の特定の場所でのブール式で、プログラムにバグがない限りtrue になります。

assertステートメントを使用して、特定のプログラムポイントにおけるコードの理解を文書化することができます。たとえば、入力(前提条件)、プログラム状態(不変条件)、または出力(事後条件)についての前提条件または保証を文書化できます。

あなたの主張が失敗したとしても、これはあなたが(あるいはあなたの後継者にとって)あなたがプログラムを書いた時にあなたのプログラムに対する理解が間違っていたこと、そしておそらくそれにはバグが含まれていることに対する警告です。

詳細については、John Regehrが Use of Assertions に関する素晴らしいブログ投稿をしています。これはPythonのassertステートメントにも当てはまります。

3
avandeursen

Pythonで予約された関数が何をするのか正確に知りたいのなら、help(enter_keyword)と入力してください。

予約キーワードを入力していることを確認してください。文字列として入力してください。

2
ytpillai

私の簡単な説明は:

  • expressionがfalseの場合はassertAssertionErrorを送出します。それ以外の場合はコードを続行します。カンマがある場合はAssertionError: whatever after commaになり、codeは次のようになります。raise AssertionError(whatever after comma)

これに関する関連チュートリアル:

https://www.tutorialspoint.com/python/assertions_in_python.htm

1
U9-Forward

Python assert は基本的にあなたのコードの内部自己チェックのための条件をテストするデバッギングエイドです。コードが不可能なEdgeケースに陥ったとき、Assertはデバッグを非常に簡単にします。主張できない事件を表明する。

割引後の商品の価格を計算する関数があるとしましょう:

def calculate_discount(price, discount):
    discounted_price = price - [discount*price]
    assert 0 <= discounted_price <= price
    return discounted_price

ここでは、discounted_priceが0より小さく、実際の価格より大きくなることはありません。したがって、上記の条件に違反した場合、assertはアサーションエラーを発生させます。これは開発者が不可能なことが起こったことを識別するのに役立ちます。

それが役に立てば幸い :)

1
Nitish Chauhan

assertステートメントは、ほとんどすべてのプログラミング言語に存在します。他の操作の副作用としてではなく、プログラムの早い段階(原因が明らかな場合)で問題を検出するのに役立ちます。彼らは常にTrue条件を期待します。

あなたが何かをするとき:

assert condition

あなたはプログラムにその状態をテストし、それが偽であれば直ちにエラーを引き起こすように言っています。

Pythonでは、 assert は次のものと同等です。

if __debug__:
    if not <expression>: raise AssertionError

拡張式を使用して、 オプションのメッセージ を渡すことができます。

if __debug__:
    if not (expression_1): raise AssertionError(expression_2)

Pythonインタプリタで試してください。

>>> assert True # Nothing happens because the condition returns a True value.
>>> assert False # A traceback is triggered because this evaluation did not yield an expected value.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError

主にassert文とif文を切り替えることを考える人々のためにそれらを使用する前に見るべきいくつかの警告があります。 assertを使用する目的は、プログラムが条件を検証し、エラーを回避するための代替手段をとる代わりに、プログラムを直ちに停止する値を返すときにあります。

1.かっこ

お気づきかもしれませんが、assertステートメントは2つの条件を使用します。したがって、 not を使用して、明らかなアドバイスのために括弧を使用してください。次のような場合

assert (condition, message)

例:

>>> assert (1==2, 1==1)
<stdin>:1: SyntaxWarning: assertion is always true, perhaps remove parentheses?

最初のパラメータとしてTupleを表す(condition, message)を指定してassertを実行します。これは、Pythonでは空でないTupleが always Trueの原因となります。ただし、問題なく個別に実行できます。

assert (condition), "message"

例:

>>> assert (1==2), ("This condition returns a %s value.") % "False"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: This condition returns a False value.

2.デバッグ目的

assertステートメントをいつ使用するかについて疑問に思っているならば。実生活で使用される例を見てください。

*あなたのプログラムがユーザによって入力された各パラメータまたは他の何でも制御する傾向があるとき:

def loremipsum(**kwargs):
    kwargs.pop('bar') # return 0 if "bar" isn't in parameter
    kwargs.setdefault('foo', type(self)) # returns `type(self)` value by default
    assert (len(kwargs) == 0), "unrecognized parameter passed in %s" % ', '.join(kwargs.keys())

*別のケースは、0または特定の方程式の係数または定数として正でない場合の数学です。

def discount(item, percent):
    price = int(item['price'] * (1.0 - percent))
    print(price)
    assert (0 <= price <= item['price']),\
            "Discounted prices cannot be lower than 0 "\
            "and they cannot be higher than the original price."

    return price

*あるいはブール値実装の簡単な例でさえ:

def true(a, b):
    assert (a == b), "False"
    return 1

def false(a, b):
    assert (a != b), "True"
    return 0

3.データ処理またはデータ検証

-Oまたは-OOフラグを使用したPythonの初期化時にこのステートメントをオフにすることができるため、データ処理やデータ検証の実行にassertステートメントに依存しないことが最も重要です。またはPYTHONOPTIMIZE環境変数。

値1:

*アサートは無効です。

*バイトコードファイルは.pyoの代わりに .pyc 拡張子を使って生成されます。

* sys.flags.optimizeは1(True)に設定されています。

*そして、__debug__Falseに設定されています。

値2: もう1つ無効にする

* docstringは無効になっています。

したがって、assertステートメントを使用してある種の予期されるデータを検証することは非常に危険であり、セキュリティ上の問題があることを意味します。それから、あなたが何らかの許可を検証する必要があるならば、私はあなたに代わりにraise AuthErrorを勧めます。前提条件として、assertは一般に、ユーザーが直接対話しないライブラリまたはモジュールに対してプログラマによって使用されます。

0
slayer