Pythonトレースバックを理解する
コードで例外が発生すると、Pythonはtracebackを出力します。 トレースバックの出力は、初めて表示する場合や、何を伝えているのかわからない場合、少々圧倒されます。 しかし、Pythonトレースバックには、コードで発生した例外の原因を診断および修正するのに役立つ豊富な情報があります。 Pythonトレースバックが提供する情報を理解することは、優れたPythonプログラマーになるために不可欠です。
このチュートリアルを終了すると、次のことができるようになります。
-
表示される次のトレースバックを理解する
-
より一般的なトレースバックのいくつかを認識する
-
例外を処理しながらトレースバックを正常に記録します
Free Bonus:Click here to get our free Python Cheat Sheetは、データ型、辞書、リスト、Python関数の操作など、Python3の基本を示しています。
Pythonトレースバックとは何ですか?
トレースバックは、特定の時点でコード内で行われた関数呼び出しを含むレポートです。 トレースバックは、stack trace、stack traceback、backtraceなど、多くの名前で知られています。 Pythonでは、使用される用語はtracebackです。
プログラムで例外が発生すると、Pythonは現在のトレースバックを出力して、何が問題なのかを知るのに役立ちます。 以下に、この状況を説明する例を示します。
# example.py
def greet(someone):
print('Hello, ' + someon)
greet('Chad')
ここで、greet()
はパラメーターsomeone
で呼び出されます。 ただし、greet()
では、その変数名は使用されません。 代わりに、print()
呼び出しでsomeon
としてスペルが間違っています。
Note:このチュートリアルは、Pythonの例外を理解していることを前提としています。 慣れていない場合、または単に復習したい場合は、Python Exceptions: An Introductionを確認する必要があります。
このプログラムを実行すると、次のトレースバックが表示されます。
$ python example.py
Traceback (most recent call last):
File "/path/to/example.py", line 4, in
greet('Chad')
File "/path/to/example.py", line 2, in greet
print('Hello, ' + someon)
NameError: name 'someon' is not defined
このトレースバック出力には、問題の診断に必要なすべての情報が含まれています。 トレースバック出力の最終行には、発生した例外のタイプと、その例外に関するいくつかの関連情報が示されます。 トレースバックの前の行は、例外が発生する原因となったコードを示しています。
上記のトレースバックでは、例外はNameError
でした。これは、定義されていない名前(変数、関数、クラス)への参照があることを意味します。 この場合、参照される名前はsomeon
です。
この場合の最終行には、問題の修正に役立つ十分な情報が含まれています。 スペルミスである名前someon
のコードを検索すると、正しい方向を示します。 ただし、多くの場合、コードははるかに複雑です。
Pythonトレースバックの読み方
Pythonトレースバックには、コードで発生した例外の理由を判断しようとするときに役立つ多くの情報が含まれています。 このセクションでは、トレースバックに含まれるさまざまな情報を理解するために、さまざまなトレースバックを順を追って説明します。
Pythonトレースバックの概要
すべてのPythonトレースバックには、重要なセクションがいくつかあります。 以下の図は、さまざまな部分を強調しています。
Pythonでは、トレースバックを下から順に読むのが最善です。
-
Blue box:トレースバックの最後の行はエラーメッセージ行です。 発生した例外名が含まれます。
-
Green box:例外名の後にエラーメッセージが表示されます。 通常、このメッセージには、例外が発生する理由を理解するのに役立つ情報が含まれています。
-
Yellow box:トレースバックのさらに上には、さまざまな関数呼び出しが下から上に移動し、最新のものから最新のものへと移動します。 これらの呼び出しは、呼び出しごとに2行のエントリで表されます。 各呼び出しの最初の行には、ファイル名、行番号、モジュール名などの情報が含まれており、すべてコードの場所を指定しています。
-
Red underline:これらの呼び出しの2行目には、実行された実際のコードが含まれています。
コマンドラインでコードを実行する場合と、REPLでコードを実行する場合のトレースバック出力には、いくつかの違いがあります。 以下は、REPLで実行された前のセクションの同じコードと、結果のトレースバック出力です。
>>>
>>> def greet(someone):
... print('Hello, ' + someon)
...
>>> greet('Chad')
Traceback (most recent call last):
File "", line 1, in
File "", line 2, in greet
NameError: name 'someon' is not defined
ファイル名の代わりに"<stdin>"
を取得することに注意してください。 これは、標準入力を介してコードを入力したので理にかなっています。 また、実行されたコード行はトレースバックに表示されません。
Note:他のプログラミング言語でスタックトレースを表示することに慣れている場合は、Pythonトレースバックの外観と比較して大きな違いに気付くでしょう。 他のほとんどの言語は、例外を一番上に表示してから、上から下へ、最近の呼び出しから最も新しいものへと呼び出します。
すでに述べましたが、繰り返しますが、Pythonトレースバックは下から上に読む必要があります。 これは非常に便利です。トレースバックが印刷され、端末(またはトレースバックを読んでいるところ)が通常出力の最後になり、トレースバックを読み始めるのに最適な場所が得られるからです。
特定のトレースバックウォークスルー
特定のトレースバック出力を調べることで、トレースバックがどのような情報を提供するかをより深く理解し、確認することができます。
以下のコードは、Pythonトレースバックが提供する情報を説明するために、次の例で使用されています。
# greetings.py
def who_to_greet(person):
return person if person else input('Greet who? ')
def greet(someone, greeting='Hello'):
print(greeting + ', ' + who_to_greet(someone))
def greet_many(people):
for person in people:
try:
greet(person)
except Exception:
print('hi, ' + person)
ここで、who_to_greet()
は値person
を取り、それを返すか、代わりに値を返すように要求します。
次に、greet()
は、挨拶する名前、someone
、およびオプションのgreeting
値を取り、print()
を呼び出します。 who_to_greet()
は、渡されたsomeone
値でも呼び出されます。
最後に、greet_many()
はpeople
のリストを反復処理し、greet()
を呼び出します。 greet()
を呼び出すことによって発生した例外がある場合、簡単なバックアップグリーティングが出力されます。
このコードには、正しい入力が提供されている限り例外が発生するバグはありません。
greetings.py
の下部にgreet()
への呼び出しを追加し、予期しないキーワード引数(たとえば、greet('Chad', greting='Yo')
)を指定すると、次のトレースバックが得られます。
$ python example.py
Traceback (most recent call last):
File "/path/to/greetings.py", line 19, in
greet('Chad', greting='Yo')
TypeError: greet() got an unexpected keyword argument 'greting'
この場合も、Pythonトレースバックを使用して、出力を上に移動して後方に作業するのが最善です。 トレースバックの最終行から、例外がTypeError
であることがわかります。 コロンの後のすべての例外タイプに続くメッセージは、いくつかの素晴らしい情報を提供します。 greet()
が予期しないキーワード引数で呼び出されたことを示しています。 不明な引数名も与えられます:greting
。
上に移動すると、例外が発生した行を確認できます。 この場合、greetings.py
の下部に追加したのはgreet()
呼び出しです。
次の行には、コードが存在するファイルへのパス、コードが見つかるファイルの行番号、およびそのモジュールが含まれています。 この場合、コードは他のPythonモジュールを使用していないため、ここに<module>
が表示されます。これは、これが実行中のファイルであることを意味します。
別のファイルと別の入力を使用すると、トレースバックが問題を見つけるために正しい方向を指し示していることがわかります。 フォローしている場合は、バグのあるgreet()
呼び出しをgreetings.py
の下部から削除し、次のファイルをディレクトリに追加します。
# example.py
from greetings import greet
greet(1)
ここでは、前のモジュールgreetings.py
をインポートし、そこからgreet()
を使用する別のPythonファイルを設定しました。 example.py
を実行すると、次のようになります。
$ python example.py
Traceback (most recent call last):
File "/path/to/example.py", line 3, in
greet(1)
File "/path/to/greetings.py", line 5, in greet
print(greeting + ', ' + who_to_greet(someone))
TypeError: must be str, not int
この場合に発生する例外は再びTypeError
ですが、今回のメッセージは少し役に立ちません。 これは、コードのどこかで文字列を処理することを期待していたが、整数が与えられたことを示しています。
上に移動すると、実行されたコード行が表示されます。 次に、コードのファイルと行番号。 ただし、今回は、<module>
の代わりに、実行されていた関数の名前greet()
を取得します。
次に実行されるコード行に移動すると、問題のあるgreet()
呼び出しが整数で渡されていることがわかります。
例外が発生した後、別のコードがその例外をキャッチし、例外が発生することもあります。 このような状況では、Pythonはすべての例外トレースバックを受信した順に出力し、再び最後に発生した例外のトレースバックで終了します。
これは少しわかりにくいので、例を示します。 greetings.py
の下部にgreet_many()
への呼び出しを追加します。
# greetings.py
...
greet_many(['Chad', 'Dan', 1])
これにより、3人全員に挨拶が印刷されます。 ただし、このコードを実行すると、複数のトレースバックが出力される例が表示されます。
$ python greetings.py
Hello, Chad
Hello, Dan
Traceback (most recent call last):
File "greetings.py", line 10, in greet_many
greet(person)
File "greetings.py", line 5, in greet
print(greeting + ', ' + who_to_greet(someone))
TypeError: must be str, not int
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "greetings.py", line 14, in
greet_many(['Chad', 'Dan', 1])
File "greetings.py", line 12, in greet_many
print('hi, ' + person)
TypeError: must be str, not int
上記の出力でDuring handling
で始まる強調表示された行に注意してください。 すべてのトレースバックの間に、この行が表示されます。 そのメッセージは非常に明確で、コードが前の例外を処理しようとしていたときに別の例外が発生しました。
Note:以前の例外トレースバックを表示するPythonの機能がPython3で追加されました。 Python 2では、最後の例外のトレースバックのみを取得します。
整数でgreet()
を呼び出したとき、前の例外を見たことがあります。 挨拶する人のリストに1
を追加したので、同じ結果が期待できます。 ただし、関数greet_many()
は、greet()
呼び出しをtry
およびexcept
ブロックにラップします。 greet()
で例外が発生した場合に備えて、greet_many()
はデフォルトのグリーティングを出力したいと考えています。
greetings.py
の関連部分は、ここで繰り返されます。
def greet_many(people):
for person in people:
try:
greet(person)
except Exception:
print('hi, ' + person)
したがって、整数入力が正しくないためにgreet()
がTypeError
になると、greet_many()
はその例外を処理し、簡単な挨拶を出力しようとします。 ここで、コードは最終的に別の同様の例外になります。 まだ文字列と整数を追加しようとしています。
トレースバックのすべての出力を見ると、例外の本当の原因が何かを確認するのに役立ちます。 最終的な例外が発生し、その結果のトレースバックが表示される場合でも、何が問題なのかがまだわからないことがあります。 そのような場合、通常、前の例外に移動すると、根本的な原因をよりよく理解できます。
Pythonの一般的なトレースバックとは何ですか?
プログラムで例外が発生したときにPythonトレースバックを読み取る方法を知っていると、プログラミングの際に非常に役立ちますが、一般的なトレースバックのいくつかを知っていると、プロセスを高速化できます。
以下に、遭遇する可能性のあるいくつかの一般的な例外、それらが発生する理由とその意味、およびトレースバックで見つけることができる情報を示します。
AttributeError
AttributeError
は、その属性が定義されていないオブジェクトの属性にアクセスしようとすると発生します。 Pythonドキュメントでは、この例外がいつ発生するかを定義しています。
属性の参照または割り当てが失敗したときに発生します。 (Source)
AttributeError
が発生する例を次に示します。
>>>
>>> an_int = 1
>>> an_int.an_attribute
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'int' object has no attribute 'an_attribute'
AttributeError
のエラーメッセージ行は、特定のオブジェクトタイプ(この場合はint
)にアクセスされた属性(この場合はan_attribute
)がないことを示しています。 エラーメッセージ行のAttributeError
を確認すると、アクセスしようとした属性とその修正先をすばやく特定するのに役立ちます。
ほとんどの場合、この例外が発生するということは、おそらく期待していたタイプではないオブジェクトを操作していることを示しています。
>>>
>>> a_list = (1, 2)
>>> a_list.append(3)
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'tuple' object has no attribute 'append'
上記の例では、a_list
が.append()
というメソッドを持つlist
型であると予想している場合があります。 AttributeError
例外を受け取り、.append()
を呼び出そうとしたときに発生したことを確認すると、期待していたタイプのオブジェクトを処理していない可能性があります。
多くの場合、これは、関数またはメソッド呼び出しからオブジェクトが返されることを期待していて、最終的にタイプNone
のオブジェクトになる場合に発生します。 この場合、エラーメッセージ行はAttributeError: 'NoneType' object has no attribute 'append'
と表示されます。
ImportError
ImportError
は、importステートメントで問題が発生したときに発生します。 インポートしようとしているモジュールが見つからない場合、またはモジュールに存在しないモジュールから何かをインポートしようとすると、この例外またはそのサブクラスModuleNotFoundError
が発生します。 Pythonドキュメントでは、この例外がいつ発生するかを定義しています。
importステートメントにモジュールのロードに問題がある場合に発生します。
from ... import
の「リストから」の名前が見つからない場合にも発生します。 (Source)
ImportError
とModuleNotFoundError
が発生する例を次に示します。
>>>
>>> import asdf
Traceback (most recent call last):
File "", line 1, in
ModuleNotFoundError: No module named 'asdf'
>>> from collections import asdf
Traceback (most recent call last):
File "", line 1, in
ImportError: cannot import name 'asdf'
上記の例では、存在しないモジュールasdf
をインポートしようとすると、ModuleNotFoundError
になることがわかります。 存在するモジュールcollections
から、存在しないものasdf
をインポートしようとすると、ImportError
になります。 トレースバックの下部にあるエラーメッセージ行は、インポートできなかったものを示しています。どちらの場合もasdf
です。
IndexError
list
or a tuple
のようにシーケンスからインデックスを取得しようとすると、IndexError
が発生しますが、シーケンス内にインデックスが見つかりません。 Pythonドキュメントでは、この例外がいつ発生するかを定義しています。
シーケンスの添え字が範囲外の場合に発生します。 (Source)
IndexError
を上げる例を次に示します。
>>>
>>> a_list = ['a', 'b']
>>> a_list[3]
Traceback (most recent call last):
File "", line 1, in
IndexError: list index out of range
IndexError
のエラーメッセージ行は、優れた情報を提供しません。 out of range
であるシーケンス参照があり、シーケンスのタイプ(この場合はlist
)であることがわかります。 通常、その情報と残りのトレースバックを組み合わせることで、問題の修正方法をすばやく特定するのに十分です。
KeyError
IndexError
と同様に、マッピングにないキー(通常はdict
)にアクセスしようとすると、KeyError
が発生します。 これをIndexError
と考えてください。ただし、dictionariesの場合です。 Pythonドキュメントでは、この例外がいつ発生するかを定義しています。
マッピング(辞書)キーが既存のキーのセットで見つからない場合に発生します。 (Source)
KeyError
が発生する例を次に示します。
>>>
>>> a_dict['b']
Traceback (most recent call last):
File "", line 1, in
KeyError: 'b'
KeyError
のエラーメッセージ行には、見つからなかったキーが表示されます。 これはあまり続けることではありませんが、残りのトレースバックと組み合わせると、通常は問題を修正するのに十分です。
KeyError
の詳細については、Python KeyError Exceptions and How to Handle Themを参照してください。
NameError
NameError
は、変数、モジュール、クラス、関数、またはコードで定義されていないその他の名前を参照した場合に発生します。 Pythonドキュメントでは、この例外がいつ発生するかを定義しています。
ローカル名またはグローバル名が見つからない場合に発生します。 (Source)
以下のコードでは、greet()
はパラメーターperson
を取ります。 しかし、関数自体では、そのパラメーターのスペルがpersn
に間違っています。
>>>
>>> def greet(person):
... print(f'Hello, {persn}')
>>> greet('World')
Traceback (most recent call last):
File "", line 1, in
File "", line 2, in greet
NameError: name 'persn' is not defined
NameError
トレースバックのエラーメッセージ行に、欠落している名前が示されています。 上記の例では、渡された関数の変数またはパラメーターのスペルが間違っています。
スペルを間違えたパラメータの場合も、NameError
が発生します。
>>>
>>> def greet(persn):
... print(f'Hello, {person}')
>>> greet('World')
Traceback (most recent call last):
File "", line 1, in
File "", line 2, in greet
NameError: name 'person' is not defined
ここでは、何も間違ったことをしていないように見えるかもしれません。 トレースバックで実行および参照された最後の行は適切に見えます。 このような状況に陥った場合は、コードを調べて、person
変数が使用および定義されている場所を探す必要があります。 ここで、パラメーター名のスペルが間違っていることがすぐにわかります。
SyntaxError
SyntaxError
は、コードに誤ったPython構文がある場合に発生します。 Pythonドキュメントでは、この例外がいつ発生するかを定義しています。
パーサーが構文エラーを検出すると発生します。 (Source)
以下の問題は、関数定義行の最後にあるはずのコロンが欠落していることです。 Python REPLでは、この構文エラーはEnterキーを押すとすぐに発生します。
>>>
>>> def greet(person)
File "", line 1
def greet(person)
^
SyntaxError: invalid syntax
SyntaxError
のエラーメッセージ行は、コードの構文に問題があったことを示しているだけです。 上記の行を調べると、問題のある行と、通常は問題のある場所を指す^
(キャレット)が表示されます。 ここでは、関数のdef
ステートメントにコロンがありません。
また、SyntaxError
トレースバックでは、通常の最初の行Traceback (most recent call last):
が欠落しています。 これは、Pythonがコードを解析しようとしたときにSyntaxError
が発生し、行が実際に実行されていないためです。
TypeError
TypeError
は、整数に文字列を追加しようとしたり、長さがnでないオブジェクトでlen()
を呼び出したりするなど、コードがそれを実行できないオブジェクトで何かを実行しようとすると発生します。定義されていません。 Pythonドキュメントでは、この例外がいつ発生するかを定義しています。
不適切なタイプのオブジェクトに操作または関数が適用されると発生します。 (Source)
以下は、TypeError
が発生するいくつかの例です。
>>>
>>> 1 + '1'
Traceback (most recent call last):
File "", line 1, in
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>> '1' + 1
Traceback (most recent call last):
File "", line 1, in
TypeError: must be str, not int
>>> len(1)
Traceback (most recent call last):
File "", line 1, in
TypeError: object of type 'int' has no len()
TypeError
を上げる上記の例はすべて、異なるメッセージを含むエラーメッセージ行になります。 それらのそれぞれは、何が間違っているかを通知するという非常に良い仕事をします。
最初の2つの例では、文字列と整数を一緒に追加しようとします。 ただし、それらは微妙に異なります。
-
1つ目は、
str
をint
に追加しようとすることです。 -
2つ目は、
int
をstr
に追加しようとしています。
エラーメッセージの行には、これらの違いが反映されています。
最後の例では、int
でlen()
を呼び出そうとします。 エラーメッセージ行は、int
ではそれができないことを示しています。
ValueError
ValueError
は、オブジェクトの値が正しくない場合に発生します。 これは、インデックスの値がシーケンスの範囲内にないために発生するIndexError
と考えることができます。より一般的なケースでは、ValueError
のみが使用されます。 Pythonドキュメントでは、この例外がいつ発生するかを定義しています。
操作または関数が正しい型であるが不適切な値の引数を受け取り、その状況が
IndexError
などのより正確な例外によって記述されていない場合に発生します。 (Source)
ValueError
が発生する2つの例を次に示します。
>>>
>>> a, b, c = [1, 2]
Traceback (most recent call last):
File "", line 1, in
ValueError: not enough values to unpack (expected 3, got 2)
>>> a, b = [1, 2, 3]
Traceback (most recent call last):
File "", line 1, in
ValueError: too many values to unpack (expected 2)
これらの例のValueError
エラーメッセージ行は、値の問題が何であるかを正確に示しています。
-
最初の例では、多くの値をアンパックしようとしています。 エラーメッセージの行には、3つの値をアンパックすることを期待していましたが、2つの値が得られたことが示されています。
-
2番目の例の問題は、取得する値が多すぎて、それらを展開するのに十分な変数がないことです。
トレースバックをどのように記録しますか?
例外とその結果のPythonトレースバックを取得するということは、その対処方法を決定する必要があることを意味します。 通常、コードを修正することが最初のステップですが、予期しない入力や間違った入力に問題がある場合があります。 コードでこれらの状況に対応するのは良いことですが、トレースバックをログに記録して他のことを行うことで、例外を沈黙させたり隠したりするのも理にかなっています。
Pythonのトレースバックを黙らせる必要がある、より現実的なコードの例を次に示します。 この例では、requests
libraryを使用しています。 あなたはPython’s Requests Library (Guide)でそれについてもっと知ることができます:
# urlcaller.py
import sys
import requests
response = requests.get(sys.argv[1])
print(response.status_code, response.content)
このコードはうまくいきます。 コマンドライン引数としてURLを指定してこのスクリプトを実行すると、URLが呼び出され、応答からHTTPステータスコードとコンテンツが出力されます。 応答がHTTPエラーステータスの場合でも機能します。
$ python urlcaller.py https://httpbin.org/status/200
200 b''
$ python urlcaller.py https://httpbin.org/status/500
500 b''
ただし、取得するためにスクリプトに指定されたURLが存在しないか、ホストサーバーがダウンしている場合があります。 このような場合、このスクリプトはキャッチされないConnectionError
例外を発生させ、トレースバックを出力します。
$ python urlcaller.py http://thisurlprobablydoesntexist.com
...
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "urlcaller.py", line 5, in
response = requests.get(sys.argv[1])
File "/path/to/requests/api.py", line 75, in get
return request('get', url, params=params, **kwargs)
File "/path/to/requests/api.py", line 60, in request
return session.request(method=method, url=url, **kwargs)
File "/path/to/requests/sessions.py", line 533, in request
resp = self.send(prep, **send_kwargs)
File "/path/to/requests/sessions.py", line 646, in send
r = adapter.send(request, **kwargs)
File "/path/to/requests/adapters.py", line 516, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='thisurlprobablydoesntexist.com', port=80): Max retries exceeded with url: / (Caused by NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known',))
ここでのPythonトレースバックは非常に長くなる可能性がありますが、他の多くの例外が発生し、最終的にConnectionError
がrequests
自体によって発生します。 最後の例外のトレースバックを上に移動すると、問題はすべて、urlcaller.py
の5行目からコードで始まっていることがわかります。
問題のある行をtry
and except
blockでラップする場合、適切な例外をキャッチすると、スクリプトはより多くの入力で引き続き機能します。
# urlcaller.py
...
try:
response = requests.get(sys.argv[1])
except requests.exceptions.ConnectionError:
print(-1, 'Connection Error')
else:
print(response.status_code, response.content)
上記のコードでは、try
およびexcept
ブロックでelse
句を使用しています。 Pythonのこの機能に慣れていない場合は、Python Exceptions: An Introductionのelse
句のセクションを確認してください。
これで、ConnectionError
が発生するURLを使用してスクリプトを実行すると、ステータスコードの-1
とコンテンツConnection Error
が出力されます。
$ python urlcaller.py http://thisurlprobablydoesntexist.com
-1 Connection Error
これはとてもうまくいきます。 ただし、ほとんどの実際のシステムでは、例外とその結果のトレースバックを黙らせるだけでなく、トレースバックを記録する必要があります。 トレースバックを記録することにより、プログラムの何が問題になっているのかをより深く理解できます。
Note: Pythonのロギングシステムの詳細については、Logging in Pythonを確認してください。
logging
パッケージをインポートし、ロガーを取得し、そのロガーでtry
および%((t3)sおよびexcept
ブロック。 最終的なスクリプトは、次のコードのようになります。
# urlcaller.py
import logging
import sys
import requests
logger = logging.getLogger(__name__)
try:
response = requests.get(sys.argv[1])
except requests.exceptions.ConnectionError as e:
logger.exception()
print(-1, 'Connection Error')
else:
print(response.status_code, response.content)
これで、問題のあるURLに対してスクリプトを実行すると、予期された-1
とConnection Error
が出力されますが、トレースバックもログに記録されます。
$ python urlcaller.py http://thisurlprobablydoesntexist.com
...
File "/path/to/requests/adapters.py", line 516, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='thisurlprobablydoesntexist.com', port=80): Max retries exceeded with url: / (Caused by NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known',))
-1 Connection Error
デフォルトでは、Pythonはログメッセージを標準エラー(stderr
)に送信します。 これは、トレースバック出力をまったく抑制していないようです。 ただし、stderr
をリダイレクトしているときに再度呼び出すと、ログシステムが機能していることがわかり、後で使用できるようにログを保存できます。
$ python urlcaller.py http://thisurlprobablydoesntexist.com 2> my-logs.log
-1 Connection Error
結論
Pythonトレースバックには、Pythonコードで何が問題なのかを見つけるのに役立つ素晴らしい情報が含まれています。 これらのトレースバックは少し威圧的に見えるかもしれませんが、それを分解して表示しようとしているものを確認すると、非常に役立ちます。 行ごとにいくつかのトレースバックを実行すると、含まれている情報をよりよく理解でき、それらを最大限に活用できます。
コードの実行時にPythonトレースバック出力を取得することは、コードを改善する機会です。 Pythonがあなたを助けようとする1つの方法です。
Pythonトレースバックの読み方がわかったので、トレースバック出力で通知されている問題を診断するためのいくつかのツールと手法についてさらに学ぶことができます。 Pythonの組み込みtraceback
moduleを使用して、トレースバックを操作および検査できます。 traceback
モジュールは、トレースバック出力をさらに活用する必要がある場合に役立ちます。 Pythonコードのいくつかのtechniques for debuggingについてさらに学ぶことも役に立ちます。