web-dev-qa-db-ja.com

Pythonでアサーションを無効にする

Pythonでアサーションを無効にするにはどうすればよいですか?

つまり、アサーションが失敗した場合、AssertionErrorをスローしないで、続行します。

それ、どうやったら出来るの?

81
Claudiu

Pythonでアサーションを無効にするにはどうすればよいですか?

単一のプロセス、環境、または単一行のコードに影響を与える複数のアプローチがあります。

それぞれを説明します。

プロセス全体

-Oフラグ(大文字のO)を使用すると、プロセス内のすべてのassertステートメントが無効になります。

例えば:

$ python -Oc "assert False"

$ python -c "assert False"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
AssertionError

無効にすると、それに続く式も実行されないことに注意してください。

$ python -Oc "assert 1/0"

$ python -c "assert 1/0"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

環境のために

環境変数を使用してこのフラグを設定することもできます。

これは、環境を使用または継承するすべてのプロセスに影響します。

たとえば、Windowsでは、環境変数を設定してからクリアします。

C:\>python -c "assert False"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
AssertionError
C:\>SET PYTHONOPTIMIZE=TRUE

C:\>python -c "assert False"

C:\>SET PYTHONOPTIMIZE=

C:\>python -c "assert False"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
AssertionError

Unixでも同じ(それぞれの機能にsetと nset を使用)

コードの単一ポイント

あなたはあなたの質問を続けます:

アサーションが失敗した場合、AssertionErrorをスローしたくないので、続行します。

実行に失敗したコードが必要な場合は、次のように、制御フローがアサーションに到達しないことを確認してください。

if False:
    assert False, "we know this fails, but we don't get here"

または、アサーションエラーをキャッチできます。

try:
    assert False, "this code runs, fails, and the exception is caught"
except AssertionError as e:
    print(repr(e))

印刷する:

AssertionError('this code runs, fails, and the exception is caught')

AssertionErrorを処理した時点から続行します。

参考文献

assertのドキュメント から:

次のようなassertステートメント:

assert expression #, optional_message

に相当

if __debug__:
    if not expression: raise AssertionError #(optional_message)

そして、

組み込み変数__debug__は通常の状況ではTrueで、最適化が要求された場合はFalse(コマンドラインオプション-O)です。

そしてさらに

__debug__への割り当ては違法です。組み込み変数の値は、インタープリターの開始時に決定されます。

使用法のドキュメントから:

-O

基本的な最適化をオンにします。これにより、コンパイル済み(バイトコード)ファイルのファイル名拡張子が.pycから.pyoに変更されます。 PYTHONOPTIMIZEも参照してください。

そして

[〜#〜] pythonoptimize [〜#〜]

これが空でない文字列に設定されている場合、-Oオプションを指定することと同じです。整数に設定する場合、-Oを複数回指定することと同じです。

60
Aaron Hall

Pythonを-Oフラグ付きで呼び出します:

test.py:

assert(False)
print 'Done'

出力:

C:\temp\py>C:\Python26\python.exe test.py
Traceback (most recent call last):
  File "test.py", line 1, in <module>
    assert(False)
AssertionError

C:\temp\py>C:\Python26\python.exe -O test.py
Done
57
Mark Rushakoff

すでに与えられている2つの回答はどちらも有効です(コマンドラインで-Oまたは-OOを使用してPythonを呼び出します)。

これらの違いは次のとおりです。

  • -O基本的な最適化をオンにします。これにより、コンパイル済み(バイトコード)ファイルのファイル名拡張子が.pycから.pyoに変更されます。

  • -OO最適化に加えて、-O破棄docstringsに加えて

Pythonドキュメント から)

15
Michael Currie

使用する python -O

$ python -O
>>> assert False
>>> 
7
John Millikin

[〜#〜]しない[〜#〜]アサーションを無効にする必要があります。他の場所に注意が向けられると、予期しないエラーが発生します。 "10のべき乗" のルール5を参照してください。

代わりに、いくつかの高価なアサーションチェックを次のような方法で保護します。

import logging
logger = logging.getLogger(__name__)

if logger.getEffectiveLevel() < logging.DEBUG:
    ok = check_expensive_property()
    assert ok, 'Run !'

重要なアサーションを保持し、assertステートメントを最適化するための1つの方法は、選択ステートメント内でそれらを上げることです。

if foo_is_broken():
    raise AssertionError('Foo is broken!')
3

最適化されたモードで実行すると、それが実行されます。

python -OO module.py
2
FogleBird