Pythonの学習-デバッグ

プログラムを一度に作成して正常に実行できる確率は非常に低く、基本的に1%以下です。修正が必要なさまざまなバグが常にあります。いくつかのバグは非常に単純です。エラーメッセージを見てください。いくつかのバグは非常に複雑です。どの変数が正しいか、どれが間違っているかを知る必要があります。したがって、デバッグメソッドのセット全体が必要です。バグ。

最初のメソッドは、print()を使用して潜在的に問題のある変数を出力する、単純でわかりやすく効果的な方法です。

def foo(s):
	n = int(s)
	print('>>>n = %d' % n)
	return 10 / n

def main():
	foo('0')

実行後の出力で、出力された変数値を見つけます。

$ python err.py
>>> n = 0
Traceback (most recent call last):
  ...
ZeroDivisionError: integer division or modulo by zero

print()を使用する最大の欠点は、将来削除する必要があることです。プログラムのあらゆる場所でprint()について考えてください。操作の結果には、多くのジャンク情報も含まれます。したがって、2番目の方法があります。

断言

表示を支援するためにprint()が使用されている場合は常に、代わりにassertを使用できます。

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をスローします。

$ python err.py
Traceback (most recent call last):
  ...
AssertionError: n is zero!

プログラムがアサートでいっぱいの場合、print()よりも優れているわけではありません。ただし、Pythonインタープリターを起動するときに、-Oパラメーターを使用してassertをオフにすることができます。

$ python -O err.py
Traceback (most recent call last):
  ...
ZeroDivisionError: division by zero

注:アサーションのスイッチ「-O」は、数字の0ではなく、英語の大文字のOです。

閉じた後、すべてのアサートステートメントをパスとして扱うことができます。

ロギング

print()をloggingに置き換えることは、3番目の方法です。assertと比較すると、loggingはエラーをスローせず、ファイルに出力できます。

import logging

s = '0'
n = int(s)
logging.info('n = %d' % n)
print(10 / n)

logging.info()は、テキストの一部を出力できます。実行すると、ZeroDivisionError以外の情報がないことがわかりました。どうした?

心配しないでください。インポートログの後に構成行を追加して、再試行してください。

import logging
logging.basicConfig(level=logging.INFO)

出力を参照してください:

$ python err.py
INFO:root:n = 0
Traceback (most recent call last):
  File "err.py", line 8, in <module>
    print(10 / n)
ZeroDivisionError: division by zero

これはロギングの利点です。ロギング情報のレベルを指定できます。デバッグ、情報、警告、エラーなどのいくつかのレベルがあります。level= INFOを指定すると、logging.debugは機能しません。同様に、level = WARNINGを指定した後、デバッグと情報は機能しません。このようにして、削除せずにさまざまなレベルの情報を安全に出力し、最終的にどのレベルの情報を出力するかを制御できます。

ロギングのもう1つの利点は、構成が簡単なため、コンソールやファイルなど、さまざまな場所にステートメントを同時に出力できることです。

pdb

4番目の方法は、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)<module>()
-> s = '0'

パラメータ-mpdbで開始した後、pdbは次に実行されるコードを見つけます-> s = '0'。コマンドlを入力して、コードを表示します。

(Pdb) l
  1     # err.py
  2  -> s = '0'
  3     n = int(s)
  4     print(10 / n)

コマンドnを入力して、コードをステップ実行します。

(Pdb) n
> /Users/michael/Github/learn-python3/samples/debug/err.py(3)<module>()
-> n = int(s)
(Pdb) n
> /Users/michael/Github/learn-python3/samples/debug/err.py(4)<module>()
-> print(10 / n)

コマンドp変数名をいつでも入力して、変数を表示できます。

(Pdb) p s
'0'
(Pdb) p n
0

コマンドqを入力してデバッグを終了し、プログラムを終了します。

(Pdb) q

pdbを介してコマンドラインでデバッグするこの方法は、理論的には全能ですが、面倒です。1000行のコードがある場合、999行目まで実行するには、いくつのコマンドを入力する必要がありますか?幸い、別のデバッグ方法があります。

pdb.set_trace()

このメソッドもpdbを使用しますが、単一のステップで実行する必要はありません。pdbをインポートし、エラーが発生する可能性のある場所にpdb.set_trace()を配置して、ブレークポイントを設定するだけです。され
、実際に魔法、PYファイルに設定してください。

err.py

pdbをインポートします

s = '0'
n = int(s)
pdb.set_trace() # 运行到这里会自动暂停
print(10 / n)

コードを実行すると、プログラムはpdb.set_trace()で自動的に一時停止し、pdbデバッグ環境に入ります。コマンドpを使用して変数を表示するか、コマンドcを使用して実行を続行できます。

$ python err.py 
> /Users/michael/Github/learn-python3/samples/debug/err.py(7)<module>()
-> print(10 / n)
(Pdb) p n
0
(Pdb) c
Traceback (most recent call last):
  File "err.py", line 7, in <module>
    print(10 / n)
ZeroDivisionError: division by zero

この方法は、pdbシングルステップデバッグを直接開始するよりもはるかに効率的ですが、それほど高くはありません。

ここに

ブレークポイントとシングルステップを設定する場合は、デバッグをサポートするIDEが必要です。

概要

プログラムを書く上で最も苦痛なのはデバッグです。プログラムは予期しないフローで実行されることがよくあります。実行する予定のステートメントはまったく実行されません。現時点では、デバッグが必要です。

IDEを使用したデバッグの方が便利ですが、最終的にはロギングが究極の武器であることがわかります。(後で体験します)

おすすめ

転載: blog.csdn.net/qq_44787943/article/details/112569335