回答:
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
。言明です。その場合、最初のパラメーターとしてタプルを使用してをassert(condition, message)
実行します。assert
(condition, message)
それらを無効にすることに関しては、python
最適化モードで実行されている場合、__debug__
はFalse
、assertステートメントは無視されます。-O
フラグを渡すだけです:
python -O script.py
関連ドキュメントについては、こちらをご覧ください。
if not condition: raise AssertError()
、なぜアサートを使用する必要があるのですか?単に短い形式のif not condition
ステートメントであること以外に、アサートが優れている条件はありますか?
if
)。詳細については、ドキュメントを参照してください:)
assert
すべての回答を読んだ後、私はまったく何も望みませんでした。
括弧に注意してください。上で指摘したように、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,)
、括弧はタプルになり、空でないタプルTrue
はブールコンテキストで評価されます。
assert (2 + 2 = 5), "Houston we've got a problem"
、大丈夫でしょう、そうですか?
assert (2 + 2 = 5), "Houston we've got a problem"
動作しません...しかし、assertステートメントとは関係ありません。条件ではないため、条件は機能しません。秒がありません=
。
他の回答で述べたassert
ように、特定の条件が真でない場合に例外をスローするのと同じです。重要な違いは、最適化オプションを使用してコードをコンパイルすると、assertステートメントが無視されることです-O
。ドキュメントには、それが言うassert expression
より良いと同等であると説明することができます
if __debug__:
if not expression: raise AssertionError
これは、コードを徹底的にテストし、アサーションケースが失敗しないことに満足したときに最適化されたバージョンをリリースする場合に役立ちます。最適化がオンの場合、__debug__
変数はFalseになり、条件は評価されなくなります。この機能は、アサーションに依存していて、アサートが消えたことに気づいていない場合にも注意を引くことができます。
if Not Error: raise Exception(“ this is a error”)
?こうすることで、プログラムはまだ..ユーザーがそれを実行したとき、エラーの原因が表示されます
assert
ステートメントを使用する必要がありますか?ここでの前提は、プログラムがエンドユーザーにリリースされるときに-Oフラグを使用しているため、すべてのバグが削除されていることを前提としています。したがって、エラーまたはプログラムのクラッシュは、契約に従って有効であるプログラムへの入力が原因ですが、プログラムでは処理できません。したがって、ユーザーに警告する必要があります。
Pythonのアサーションの目的は、プログラムの回復不可能なエラーについて開発者に通知することです。
アサーションは、「ファイルが見つかりません」など、ユーザーが修正措置を講じることができる(または単に再試行する)可能性のあるエラー条件を通知することを目的としていません。
これを見る別の方法は、アサーションはコードの内部セルフチェックであると言うことです。これらは、コードで一部の条件を不可能として宣言することで機能します。これらの条件が満たされない場合は、プログラムにバグがあることを意味します。
プログラムにバグがない場合、これらの条件は発生しません。しかし、それらのいずれかが発生した場合、プログラムは、どの「不可能」な状態がトリガーされたかを正確に伝えるアサーションエラーでクラッシュします。これにより、プログラム内のバグの追跡と修正がはるかに簡単になります。
以下は、私が書いたPythonのアサーションに関するチュートリアルの要約です。
Pythonのassertステートメントはデバッグの補助であり、実行時エラーを処理するメカニズムではありません。アサーションを使用する目的は、開発者がバグの根本的な原因をより迅速に見つけられるようにすることです。プログラムにバグがない限り、アサーションエラーが発生することはありません。
assert
ステートメントとこれを使用するタイミングを理解するのに非常に役立ちます。記事で紹介したいくつかの用語を理解しようとしています。
assert store.product_exists(product_id), 'Unknown product id'
はお勧めできません。デバッグがオフになっuser
ているadmin
と、製品を削除できなくなるからです。あなたは考えるかassert user.is_admin()
のようにunrecoverable
エラー?これはなぜself-check
ですか?
assert statement
カントは、price
また、ユーザの入力とみなされますか?なぜassert user.is_admin()
データ検証と見なすのassert price
ですか?
他の人はすでにドキュメントへのリンクを提供しています。
対話型シェルで次のことを試すことができます。
>>> assert 5 > 2
>>> assert 2 > 5
Traceback (most recent call last):
File "<string>", line 1, in <fragment>
builtins.AssertionError:
最初のステートメントは何もせず、2番目のステートメントは例外を発生させます。これが最初のヒントです。アサートは、コードの特定の位置(通常、関数の開始(前提条件)と終了(事後条件))でtrueになるはずの条件をチェックするのに役立ちます。
アサートは実際には契約によるプログラミングに強く結びついており、これは非常に便利なエンジニアリング手法です。
ドキュメントから:
Assert statements are a convenient way to insert debugging assertions into a program
ここであなたはもっと読むことができます:http : //docs.python.org/release/2.5.2/ref/assert.html
アサーションは、プログラムの内部状態がプログラマが期待したとおりであることを確認する体系的な方法であり、バグをキャッチすることを目的としています。以下の例を参照してください。
>>> 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!
>>>
これは簡単な例です。これをファイルに保存します(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
assert
声明は、ほとんどすべてのプログラミング言語に存在します。これは、他の操作の副作用としてではなく、原因が明らかなプログラムの早い段階で問題を検出するのに役立ちます。彼らは常にTrue
状態を期待しています。
次のようなことをすると:
assert condition
その条件をテストし、それがfalseの場合はすぐにエラーをトリガーするようにプログラムに指示しています。
Pythonでは、assert
expressionは次と同等です。
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
and if
ステートメントを切り替えると考える人のためにそれらを使用する前に見られるいくつかの警告があります。使用する目的assert
は、プログラムが条件を検証し、エラーをバイパスする別の方法をとるのではなく、プログラムをすぐに停止する必要がある値を返す場合です。
お気づきかもしれませんが、このassert
ステートメントでは2つの条件を使用しています。したがって、明確なアドバイスのために、括弧を使用して括弧を付けないでください。次のような場合:
assert (condition, message)
例:
>>> assert (1==2, 1==1)
<stdin>:1: SyntaxWarning: assertion is always true, perhaps remove parentheses?
最初のパラメーターとしてタプルを表すaを使用assert
して(condition, message)
を実行すると、Pythonで空でないタプルが常にに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.
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
assert
このステートメントは、Pythonの初期化-O
または-OO
フラグ(それぞれ値1、2、および0(デフォルト)を意味する)またはPYTHONOPTIMIZE
環境変数でオフにできるため、データ処理またはデータ検証を実行するステートメントに依存しないことが最も重要です。 。
値1:
*アサートは無効です。
*バイトコードファイルは、の.pyo
代わりに拡張子を使用して生成されます.pyc
。
* sys.flags.optimize
は1(True
)に設定されます。
*そして、__debug__
に設定されFalse
ます。
値2: 1つ以上のものを無効にします
* docstringsは無効です。
したがって、このassert
ステートメントを使用してある種の予期されるデータを検証することは非常に危険であり、いくつかのセキュリティ問題をも意味します。次に、いくつかの権限を検証する必要がある場合は、raise AuthError
代わりにお勧めします。前提条件の効果として、assert
は、ユーザーが直接操作しないライブラリまたはモジュールのプログラマーによって一般的に使用されます。
C2 Wikiに簡潔に要約されているように:
アサーションは、プログラムの特定のポイントでのブール式であり、プログラムにバグがない限り trueになります。
assert
ステートメントを使用して、特定のプログラムポイントでのコードの理解を文書化できます。たとえば、入力(前提条件)、プログラムの状態(不変条件)、または出力(事後条件)に関する仮定または保証を文書化できます。
アサーションが失敗した場合、これはあなた(またはあなたの後継者)にとって、あなたがプログラムを書いたときのあなたのプログラムの理解が間違っていたこと、そしておそらくバグが含まれていることの警告です。
詳細については、John RegehrがUse of Assertionsに関するすばらしいブログ投稿を公開してassert
います。これはPython ステートメントにも適用されます。
Python アサートは基本的に、コードの内部セルフチェックの条件をテストするデバッグ補助機能です。Assertは、コードが不可能なエッジケースに陥ったときにデバッグを非常に簡単にします。それらの不可能なケースを確認してください。
割引後の商品の価格を計算する関数があるとしましょう:
def calculate_discount(price, discount):
discounted_price = price - [discount*price]
assert 0 <= discounted_price <= price
return discounted_price
ここでは、discounted_priceを0未満にして実際の価格より高くすることはできません。したがって、上記の条件に違反した場合、assertはアサーションエラーを発生させます。これは、開発者が不可能なことが起こったことを識別するのに役立ちます。
それが役に立てば幸い :)
assert
デバッグコンテキストで役立ちますが、デバッグコンテキスト以外では信頼すべきではありません。
私の簡単な説明は:
assert
AssertionError
expressionがfalseの場合に発生します。それ以外の場合はコードを継続し、コンマがある場合はそれが何であれAssertionError: whatever after comma
、コードは次のようになります。raise AssertionError(whatever after comma)
これに関する関連チュートリアル:
https://www.tutorialspoint.com/python/assertions_in_python.htm
assert
が、を使用する(または使用しない)ときは提供しませんassert
。また、assert
が便利な場合__debug__
は無効にできることに注意してくださいFalse
。
あなたが使用している場合Pycharmでは、assert
一緒にisinstance
オブジェクトの型を宣言するために、それはあなたがコーディングしている間、それは自動的にオートコンプリートはあなたが親オブジェクトのメソッドや属性にアクセスできるようになります。
たとえばself.object1.object2
、MyClass
オブジェクトであるとしましょう。
import MyClasss
def code_it(self):
testObject = self.object1.object2 # at this point, program doesn't know that testObject is a MyClass object yet
assert isinstance(testObject , MyClasss) # now the program knows testObject is a MyClass object
testObject.do_it() # from this point on, PyCharm will be able to auto-complete when you are working on testObject
他の回答で書かれているように、assert
ステートメントは、特定の時点でのプログラムの状態をチェックするために使用されます。
関連するメッセージ、括弧、または-O
オプションと__debug__
定数について言われたことは繰り返さない。直接の情報については、ドキュメントも確認してください。私はあなたの質問に焦点を当てます:何の使用assert
ですか?より正確には、いつ(そしてそうでない場合)を使用する必要がありますassert
か?
assert
文は、プログラムをデバッグするのに有用であるが、ユーザーの入力をチェックするために落胆しました。私は次の経験則を使用します。アサーションを保持して、これが発生してはならない状況を検出します。ユーザーの入力が正しくない可能性があります(たとえば、パスワードが短すぎるなど)が、これは起こり得ないケースではありません。円の直径が半径の2倍ではない場合、これは起こり得ないケースです。
私の心の中で最も興味深いのassert
は、[オブジェクト指向のソフトウェア構築](https://www.eiffel.org/doc/eiffel/Object-Oriented_Software_Construction%)の B. Meyerによって説明されている契約によるプログラミングに触発された
ものです。
2C_2nd_Edition
)[Eiffelプログラミング言語](https://en.wikipedia.org/wiki/Eiffel_ (programming_language))で実装されてい
ます。assert
ステートメントを使用してコントラクトでプログラミングを完全にエミュレートすることはできませんが、意図を維持することは興味深いことです。
ここに例があります。head
([ head
Haskellの関数](
http://www.zvon.org/other/haskell/Outputprelude/head_f.html)のような)関数を書く必要があると想像してください。指定された仕様は、「リストが空でない場合、リストの最初の項目を返す」です。次の実装を見てください。
>>> def head1(xs): return xs[0]
そして
>>> def head2(xs):
... if len(xs) > 0:
... return xs[0]
... else:
... return None
(はい、これはと書くことができますがreturn xs[0] if xs else None
、それはポイントではありません)。
リストが空でない場合、両方の関数の結果は同じであり、この結果は正しいです。
>>> head1([1, 2, 3]) == head2([1, 2, 3]) == 1
True
したがって、どちらの実装も(私は願っています)正しいです。空のリストの先頭アイテムを取得しようとすると、これらは異なります。
>>> head1([])
Traceback (most recent call last):
...
IndexError: list index out of range
だが:
>>> head2([]) is None
True
繰り返しますが、空のリストをこれらの関数に渡してはならないため、どちらの実装も正しいです(仕様外です)。それは間違った呼び出しですが、そのような呼び出しを行うと、何が起こる可能性があります。1つの関数は例外を発生させ、もう1つの関数は特別な値を返します。最も重要なのは、この動作に依存できないことです。xs
空の場合、これは動作します:
print(head2(xs))
しかし、これはプログラムをクラッシュさせます:
print(head1(xs))
予期せぬ事態を避けるために、予期しない引数を関数に渡すときを知りたいと思います。言い換えると、仕様ではなく実装に依存するため、観測可能な動作が信頼できない場合について知りたいのです。もちろん、私は仕様を読むことができますが、プログラマーは常にドキュメントを注意深く読むとは限りません。
次の効果を得るためにコードに仕様を挿入する方法があると想像してください。たとえば、空のリストをに渡すなどして仕様に違反するとhead
、警告が表示されます。これは、正しい(つまり、仕様に準拠した)プログラムを作成するのに非常に役立ちます。そして、それassert
はシーンに入るところです:
>>> def head1(xs):
... assert len(xs) > 0, "The list must not be empty"
... return xs[0]
そして
>>> def head2(xs):
... assert len(xs) > 0, "The list must not be empty"
... if len(xs) > 0:
... return xs[0]
... else:
... return None
今、私たちは持っています:
>>> head1([])
Traceback (most recent call last):
...
AssertionError: The list must not be empty
そして:
>>> head2([])
Traceback (most recent call last):
...
AssertionError: The list must not be empty
注head1
スローAssertionError
、ありませんIndexError
。ので、それは重要なのAssertionError
ではない任意のランタイムエラー:それは仕様の違反を通知します。警告が必要でしたが、エラーが発生しました。幸い、私はチェックを無効にすることができ-O
ます(オプションを使用して)が、私自身のリスクで。クラッシュは本当に高くつきますし、ベストを願っています。プログラムがブラックホールを通過する宇宙船に埋め込まれていると想像してください。アサーションを無効にし、プログラムができるだけ長くクラッシュしないように十分に堅牢であることを願っています。
この例は、assert
事後条件(戻り値または状態、あるいはその両方)と不変条件(クラスの状態)をチェックするために使用できるという前提条件のみに関するものでした。を使用して事後条件と不変条件をチェックassert
するのは面倒な場合があります。
エッフェルほど洗練されたものはありませんが、プログラムの全体的な品質を向上させることができます。
要約すると、このassert
ステートメントは、これが発生してはならない状況を検出する便利な方法です。仕様の違反(たとえば、空のリストをに渡すhead
)は最初のクラスであり、これは状況では発生しません。したがって、このassert
ステートメントは予期しない状況を検出するために使用できますが、仕様が確実に満たされるようにするための特権的な方法です。assert
コードにステートメントを挿入して仕様を表すと、不正な引数、不正な戻り値、不正なクラスの状態などが報告されるため、プログラムの品質が向上したことを願っています。
format:assert Expression [、arguments] assertがステートメントを検出すると、Pythonは式を評価します。ステートメントがtrueでない場合は、例外が発生します(assertionError)。アサーションが失敗すると、PythonはAssertionErrorの引数としてArgumentExpressionを使用します。AssertionError例外は、try-exceptステートメントを使用して他の例外と同様にキャッチおよび処理できますが、処理されない場合、プログラムが終了し、トレースバックが生成されます。例:
def KelvinToFahrenheit(Temperature):
assert (Temperature >= 0),"Colder than absolute zero!"
return ((Temperature-273)*1.8)+32
print KelvinToFahrenheit(273)
print int(KelvinToFahrenheit(505.78))
print KelvinToFahrenheit(-5)
上記のコードを実行すると、次の結果が生成されます。
32.0
451
Traceback (most recent call last):
File "test.py", line 9, in <module>
print KelvinToFahrenheit(-5)
File "test.py", line 4, in KelvinToFahrenheit
assert (Temperature >= 0),"Colder than absolute zero!"
AssertionError: Colder than absolute zero!
def getUser(self, id, Email):
user_key = id and id or Email
assert user_key
関数呼び出しでパラメーターが渡されるようにするために使用できます。
if not user_key: raise ValueError()
最後の2段落をチェックしてください:wiki.python.org/moin/UsingAssertionsEffectively
assert
の場合__debug__
は検証が削除されるため、入力の検証には使用しないでくださいFalse
。また、デバッグ以外の目的でアサーションを使用すると、結果AssertionError
のをキャッチし、デバッグを難しくする可能性があります。
>>>this_is_very_complex_function_result = 9
>>>c = this_is_very_complex_function_result
>>>test_us = (c < 4)
>>> #first we try without assert
>>>if test_us == True:
print("YES! I am right!")
else:
print("I am Wrong, but the program still RUNS!")
I am Wrong, but the program still RUNS!
>>> #now we try with assert
>>> assert test_us
Traceback (most recent call last):
File "<pyshell#52>", line 1, in <module>
assert test_us
AssertionError
>>>
基本的に、assertキーワードの意味は、条件がtrueでない場合、assertionerrorを介して、それ以外の場合は、たとえばpythonで継続することです。
コード-1
a=5
b=6
assert a==b
出力:
assert a==b
AssertionError
コード-2
a=5
b=5
assert a==b
出力:
Process finished with exit code 0
assert
していますが、を使用する(または使用しない)場合については回答していませんassert
。