14

これはかなり役に立たないアサーション エラーです。関連する式の値はわかりません (使用される定数は実際には変数名であると仮定します)。

$ python -c "assert 6-(3*2)"
[...]
AssertionError

assertより派手なPythonでのより良い実装はありますか? -O実行時に追加のオーバーヘッドを導入してはならず (アサートが失敗した場合を除く)、フラグが使用されている場合はオフにする必要があります。

編集: assert の 2 番目の引数が文字列であることは知っています。.. は、アサートされている式にエンコードされているため、書きたくありません。DRY (繰り返さないでください)。

4

7 に答える 7

11

あなたの機能を次のようにインストールしてください-ドキュメントsys.excepthookを参照してください。関数は、2 番目の引数が の場合、心ゆくまで内省できます。特に、3 番目の引数である traceback を介して、アサートが失敗したフレームと正確な場所を取得し、ソースまたはバイトコードから失敗した例外を取得し、関連するすべての変数の値などを取得できます。モジュールの検査が役立ちます。AssertionError

それを完全に一般化するのはかなりの作業ですが、asserts の記述方法で受け入れる意思のある制約によっては、大幅に軽減できます (たとえば、それらをローカル変数またはグローバル変数のみに制限すると、非ローカル変数の場合よりもイントロスペクションが容易になります)クロージャーの変数が含まれる可能性があるなど)。

于 2009-08-21T02:25:37.153 に答える
7

にメッセージを添付できますassert

assert 6-(3*2), "always fails"

メッセージは動的に作成することもできます。

assert x != 0, "x is not equal to zero (%d)" % x

詳細については、Pythonドキュメントassertステートメントを参照してください。

于 2009-08-20T20:28:04.790 に答える
7

@Mark Rushakoff が言った ようにnose、失敗したアサートを評価できます。標準でも動作しassertます。

# test_error_reporting.py
def test():
    a,b,c = 6, 2, 3
    assert a - b*c

nosetests' ヘルプ:

$ nosetests --help|grep -B2 assert
  -d, --detailed-errors, --failure-detail
                        Add detail to error output by attempting to evaluate
                        failed asserts [NOSE_DETAILED_ERRORS]

例:

$ nosetests -d
F
======================================================================
FAIL: test_error_reporting.test
----------------------------------------------------------------------
Traceback (most recent call last):
  File "..snip../site-packages/nose/case.py", line 183, in runTest
    self.test(*self.arg)
  File "..snip../test_error_reporting.py", line 3, in test
    assert a - b*c
AssertionError:
    6,2,3 = 6, 2, 3
>>  assert 6 - 2*3


----------------------------------------------------------------------
Ran 1 test in 0.089s

FAILED (failures=1)
于 2009-08-20T21:49:36.483 に答える
2

sys.excepthook標準のものよりも少し派手な (未処理の例外に対して呼び出される)の置換をコーディングしました。例外が発生した行を分析し、この行で参照されているすべての変数を出力します (ノイズが多すぎる可能性があるため、すべてのローカル変数を出力するわけではありません。また、重要な var がグローバルなどである可能性もあります)。

私はこれを py_better_exchook (完璧な名前) と呼び、ここにあります。

サンプルファイル:

a = 6

def test():
    unrelated_var = 43
    b,c = 2, 3
    assert a - b*c

import better_exchook
better_exchook.install()

test()

出力:

$ python test_error_reporting.py 
EXCEPTION
Traceback (most recent call last):
  File "test_error_reporting.py", line 12, in <module>
    line: test()
    locals:
      test = <local> <function test at 0x7fd91b1a05f0>
  File "test_error_reporting.py", line 7, in test
    line: assert a - b*c
    locals:
      a = <global> 6
      b = <local> 2
      c = <local> 3
AssertionError

他にもいくつかの代替手段があります。

于 2016-03-08T09:57:37.633 に答える
0

アサーションにメッセージを追加します。このメッセージは、アサーションが失敗した場合に表示されます。

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

これを自動的に提供することを考えることができる唯一の方法は、プロシージャ呼び出しにアサーションを含めてから、スタックを調べてその行のソースコードを取得することです。残念ながら、追加の呼び出しはテストにオーバーヘッドを導入し、で無効にすることはできません-O

于 2009-08-20T20:29:13.260 に答える