Python学習のエラーデバッグとテスト
13719 ワード
Python学習ディレクトリMacでPython 3を使う Python学習データ型 Python学習の関数 Python学習の高級特性 Python学習の関数式プログラミング Python学習のモジュール Python学習の対象向けプログラミング Python学習の対象向け高度プログラミング Python学習のエラーデバッグとテスト Python学習のIOプログラミング Python学習のプロセスとスレッド Python学習の正則 Python学習の常用モジュール Python学習のネットワークプログラミング プログラムの実行中、さまざまなエラーが発生します.Pythonには、エラー処理を支援する異常処理メカニズムが内蔵されています.
エラー処理
エラー処理
プログラムの実行中にエラーが発生した場合は、エラーコードを返すことを事前に約束することで、エラーの有無やエラーの原因を知ることができます.オペレーティングシステムが提供する呼び出しでは、エラーコードを返すのが一般的です.たとえばファイルを開く関数open()
成功した場合はファイル記述子(整数)を返し、エラーが発生した場合は-1
を返します.
エラーコードでエラーが発生したかどうかを表すのは不便で、関数自体が返すべき正常な結果とエラーコードが混在しているため、呼び出し者は大量のコードでエラーが発生したかどうかを判断しなければならないため、高級言語には通常try...except...finally...
のエラー処理メカニズムが内蔵されており、Pythonも例外ではない.
try
try:
print('try...')
r = 10 / 0
print('result:', r)
except ZeroDivisionError as e:
print('except:', e)
finally:
print('finally...')
print('END')
一部のコードでエラーが発生する可能性があると判断した場合、try
でこのコードを実行することができ、エラーが発生した場合、後続のコードは実行されず、そのままエラー処理コード、すなわちexcept
文ブロックにジャンプし、実行が完了except
後、finally
文ブロックがあれば、finally
文ブロックを実行し、これで実行が完了する.
Pythonのエラーも実はclassで、すべてのエラータイプはBaseException
から継承されているので、except
を使用するときに注意しなければならないのは、そのタイプのエラーをキャプチャするだけでなく、そのサブクラスも「一網打尽」にすることです.
呼び出しスタック
エラーがキャプチャされていない場合は、常に上に投げ出され、最後にPython解釈器にキャプチャされ、エラーメッセージが印刷され、プログラムが終了します.見てみるとerr.py
:# err.py:
def foo(s):
return 10 / int(s)
def bar(s):
return foo(s) * 2
def main():
bar('0')
main()
実行結果は次のとおりです.$ python3 err.py
Traceback (most recent call last):
File "err.py", line 11, in
main()
File "err.py", line 9, in main
bar('0')
File "err.py", line 6, in bar
return foo(s) * 2
File "err.py", line 3, in foo
return 10 / int(s)
ZeroDivisionError: division by zero
エラーの呼び出し関数チェーン全体が上から下に表示されます.
レコードエラー
エラーをキャプチャしなければ、Python解釈器にエラースタックを印刷させることは自然にできますが、プログラムも終了します.エラーをキャプチャできる以上、エラースタックを印刷し、エラーの原因を分析しながら、プログラムを実行し続けることができます.
Python内蔵logging
モジュールは非常に簡単にエラーメッセージを記録できる:# err_logging.py
import logging
def foo(s):
return 10 / int(s)
def bar(s):
return foo(s) * 2
def main():
try:
bar('0')
except Exception as e:
logging.exception(e)
main()
print('END')
上記のモジュールを実行します.$ python3 err_logging.py
ERROR:root:division by zero
Traceback (most recent call last):
File "err_logging.py", line 13, in main
bar('0')
File "err_logging.py", line 9, in bar
return foo(s) * 2
File "err_logging.py", line 6, in foo
return 10 / int(s)
ZeroDivisionError: division by zero
END
エラーを投げ出す
エラーはclassであるため、エラーをキャプチャすることはclassにキャプチャされたインスタンスです.したがって、エラーは空で発生するのではなく、意図的に作成され、投げ出されます.Pythonの内蔵関数は多くのタイプのエラーを投げ出し、私たちが自分で書いた関数もエラーを投げ出すことができます.
エラーを投げ出す場合は、まず必要に応じて、エラーのclassを定義し、継承関係を選択し、次に、raise
文でエラーのインスタンスを投げ出すことができます.# err_raise.py
class FooError(ValueError):
pass
def foo(s):
n = int(s)
if n==0:
raise FooError('invalid value: %s' % s)
return 10 / n
foo('0')
実行すると、自分たちが定義したエラーを最後に追跡できます.$ python3 err_raise.py
Traceback (most recent call last):
File "err_throw.py", line 11, in
foo('0')
File "err_throw.py", line 8, in foo
raise FooError('invalid value: %s' % s)
__main__.FooError: invalid value: 0
最後に、別のエラー処理方法を見てみましょう.# err_reraise.py
def foo(s):
n = int(s)
if n==0:
raise ValueError('invalid value: %s' % s)
return 10 / n
def bar():
try:
foo('0')
except ValueError as e:
print('ValueError!')
raise
bar()
bar()
関数では、エラーをキャプチャしているのに、1つValueError!
を印刷してから、またエラーを通過raise
文を投げ出してしまいました.
実はこのような誤った処理方法は病気ではないだけでなく、かなりよく見られます.エラーをキャプチャする目的は記録するだけで、後続の追跡に便利です.しかし,現在の関数ではこのエラーをどのように処理すべきか分からないため,最上位呼び出し者に処理させ続けるのが最も適切である.例えば、従業員が一つの問題を処理できないときは、問題を彼のボスに投げて、もし彼のボスも処理できないならば、ずっと上に投げて、最終的にCEOに投げて処理します.raise
文はパラメータを持たないと現在のエラーをそのまま投げ出す.また、except
中raise
1つのErrorは、1つのタイプのエラーを別のタイプに変換することもできます.try:
10 / 0
except ZeroDivisionError:
raise ValueError('input error!')
デバッグ
プログラムが一度に書き終わり、正常に動作する確率は小さく、基本的に1%を超えない.いつもいろいろなバグを修正する必要があります.あるバグは簡単で、エラー情報を見るとわかります.あるバグは複雑で、エラーが発生したとき、どの変数の値が正しいのか、どの変数の値が間違っているのかを知る必要があります.そのため、デバッグプログラム全体の手段でバグを修復する必要があります.
print()
print()
問題があるかもしれない変数を印刷してみます.
断言する
def foo(s):
n = int(s)
assert n != 0, 'n is zero!'
return 10 / n
def main():
foo('0')
assert
という意味で、式n != 0
であるべきTrue
そうでなければ、プログラムが実行するロジックによって、後のコードが間違いになるに違いない.
断言に失敗するとassert
文自体が投げ出されるAssertionError
.
logging
loggingでは、記録情報のレベルを指定できます.debug
、info
、warning
、error
などいくつかのレベルがあります.level=INFO
を指定すると、logging.debug
機能しません.同様に、level=WARNING
を指定すると、debug
とinfo
が機能しなくなります.これにより、異なるレベルの情報を安心して出力したり、削除したりせずに、どのレベルの情報を出力するかを統一的に制御することができます.logging
もう1つの利点は、簡単な構成により、consoleやファイルなど、1つの文を同時に異なる場所に出力できることです.import logging
logging.basicConfig(level=logging.INFO)
s = '0'
n = int(s)
logging.info('n = %d' % n)
print(10 / n)
pdb
Pythonのデバッガpdbは、プログラムを単一ステップで実行させ、いつでも実行状態を表示することができます.まずプログラムを用意します.# err.py
s = '0'
n = int(s)
print(10 / n)
次の操作を行います.$ python -m pdb err.py
> /Users/michael/Github/learn-python3/samples/debug/err.py(2)()
-> s = '0'
パラメータ-m pdb
で起動後、pdbは次の実行コード-> s = '0'
にナビゲートします.コマンドを入力l
コードを表示するには:(Pdb) l
1 # err.py
2 -> s = '0'
3 n = int(s)
4 print(10 / n)
入力コマンドn
コードはワンステップで実行できます.
pdb.set_trace()
この方法もpdbですが、単一ステップで実行する必要はありません.import pdb
、そして、エラーが発生する可能性のある場所にpdb.set_trace()
を置くだけで、ブレークポイントを設定できます.# err.py
import pdb
s = '0'
n = int(s)
pdb.set_trace() #
print(10 / n)
コードを実行すると、プログラムは自動的にpdb.set_trace()
pdbデバッグ環境に一時停止し、コマンドp
変数を表示するか、コマンドc
で実行を続行できます.
IDE
現在比較的良いPython IDEは以下の通りです.
isual Studio Code:code.visualstudio.com/、Pythonプラグインをインストールする必要があります.
PyCharm:www.jetbrains.com/pycharm/
また、Eclipseにpydevプラグインを追加してPythonプログラムをデバッグすることもできます.
ユニットテスト
ユニットテストは、モジュール、関数、またはクラスに対して正確性検査を行うためのテスト作業です.
ドキュメントテスト
Pythonの公式ドキュメントをよく読むと、多くのドキュメントにサンプルコードが表示されます.
これらのサンプルコードはPythonのインタラクティブな環境で入力して実行することができ、結果はドキュメントのサンプルコードの表示と一致します.
これらのコードは、他の説明とコメントに書くことができ、いくつかのツールによってドキュメントを自動的に生成します.
上一篇:Python学习のIOプログラミング
try:
print('try...')
r = 10 / 0
print('result:', r)
except ZeroDivisionError as e:
print('except:', e)
finally:
print('finally...')
print('END')
# err.py:
def foo(s):
return 10 / int(s)
def bar(s):
return foo(s) * 2
def main():
bar('0')
main()
$ python3 err.py
Traceback (most recent call last):
File "err.py", line 11, in
main()
File "err.py", line 9, in main
bar('0')
File "err.py", line 6, in bar
return foo(s) * 2
File "err.py", line 3, in foo
return 10 / int(s)
ZeroDivisionError: division by zero
# err_logging.py
import logging
def foo(s):
return 10 / int(s)
def bar(s):
return foo(s) * 2
def main():
try:
bar('0')
except Exception as e:
logging.exception(e)
main()
print('END')
$ python3 err_logging.py
ERROR:root:division by zero
Traceback (most recent call last):
File "err_logging.py", line 13, in main
bar('0')
File "err_logging.py", line 9, in bar
return foo(s) * 2
File "err_logging.py", line 6, in foo
return 10 / int(s)
ZeroDivisionError: division by zero
END
# err_raise.py
class FooError(ValueError):
pass
def foo(s):
n = int(s)
if n==0:
raise FooError('invalid value: %s' % s)
return 10 / n
foo('0')
$ python3 err_raise.py
Traceback (most recent call last):
File "err_throw.py", line 11, in
foo('0')
File "err_throw.py", line 8, in foo
raise FooError('invalid value: %s' % s)
__main__.FooError: invalid value: 0
# err_reraise.py
def foo(s):
n = int(s)
if n==0:
raise ValueError('invalid value: %s' % s)
return 10 / n
def bar():
try:
foo('0')
except ValueError as e:
print('ValueError!')
raise
bar()
try:
10 / 0
except ZeroDivisionError:
raise ValueError('input error!')
プログラムが一度に書き終わり、正常に動作する確率は小さく、基本的に1%を超えない.いつもいろいろなバグを修正する必要があります.あるバグは簡単で、エラー情報を見るとわかります.あるバグは複雑で、エラーが発生したとき、どの変数の値が正しいのか、どの変数の値が間違っているのかを知る必要があります.そのため、デバッグプログラム全体の手段でバグを修復する必要があります.
print()
print()
問題があるかもしれない変数を印刷してみます.断言する
def foo(s):
n = int(s)
assert n != 0, 'n is zero!'
return 10 / n
def main():
foo('0')
assert
という意味で、式n != 0
であるべきTrue
そうでなければ、プログラムが実行するロジックによって、後のコードが間違いになるに違いない.断言に失敗すると
assert
文自体が投げ出されるAssertionError
.logging
loggingでは、記録情報のレベルを指定できます.
debug
、info
、warning
、error
などいくつかのレベルがあります.level=INFO
を指定すると、logging.debug
機能しません.同様に、level=WARNING
を指定すると、debug
とinfo
が機能しなくなります.これにより、異なるレベルの情報を安心して出力したり、削除したりせずに、どのレベルの情報を出力するかを統一的に制御することができます.logging
もう1つの利点は、簡単な構成により、consoleやファイルなど、1つの文を同時に異なる場所に出力できることです.import logging
logging.basicConfig(level=logging.INFO)
s = '0'
n = int(s)
logging.info('n = %d' % n)
print(10 / n)
pdb
Pythonのデバッガpdbは、プログラムを単一ステップで実行させ、いつでも実行状態を表示することができます.まずプログラムを用意します.
# err.py
s = '0'
n = int(s)
print(10 / n)
次の操作を行います.
$ python -m pdb err.py
> /Users/michael/Github/learn-python3/samples/debug/err.py(2)()
-> s = '0'
パラメータ
-m pdb
で起動後、pdbは次の実行コード-> s = '0'
にナビゲートします.コマンドを入力l
コードを表示するには:(Pdb) l
1 # err.py
2 -> s = '0'
3 n = int(s)
4 print(10 / n)
入力コマンド
n
コードはワンステップで実行できます.pdb.set_trace()
この方法もpdbですが、単一ステップで実行する必要はありません.
import pdb
、そして、エラーが発生する可能性のある場所にpdb.set_trace()
を置くだけで、ブレークポイントを設定できます.# err.py
import pdb
s = '0'
n = int(s)
pdb.set_trace() #
print(10 / n)
コードを実行すると、プログラムは自動的に
pdb.set_trace()
pdbデバッグ環境に一時停止し、コマンドp
変数を表示するか、コマンドc
で実行を続行できます.IDE
現在比較的良いPython IDEは以下の通りです.
isual Studio Code:code.visualstudio.com/、Pythonプラグインをインストールする必要があります.
PyCharm:www.jetbrains.com/pycharm/
また、Eclipseにpydevプラグインを追加してPythonプログラムをデバッグすることもできます.
ユニットテスト
ユニットテストは、モジュール、関数、またはクラスに対して正確性検査を行うためのテスト作業です.
ドキュメントテスト
Pythonの公式ドキュメントをよく読むと、多くのドキュメントにサンプルコードが表示されます.
これらのサンプルコードはPythonのインタラクティブな環境で入力して実行することができ、結果はドキュメントのサンプルコードの表示と一致します.
これらのコードは、他の説明とコメントに書くことができ、いくつかのツールによってドキュメントを自動的に生成します.
上一篇:Python学习のIOプログラミング
Pythonの公式ドキュメントをよく読むと、多くのドキュメントにサンプルコードが表示されます.
これらのサンプルコードはPythonのインタラクティブな環境で入力して実行することができ、結果はドキュメントのサンプルコードの表示と一致します.
これらのコードは、他の説明とコメントに書くことができ、いくつかのツールによってドキュメントを自動的に生成します.
上一篇:Python学习のIOプログラミング