次のおもちゃの例を考えてみましょう。
def twice(n):
_validate_twice_args(n)
return 2*n
def _validate_twice_args(n):
if type(n) != int:
raise TypeError('n must be an int')
twice(None)
--
Traceback (most recent call last):
File "demo.py", line 9, in <module>
twice(None)
File "demo.py", line 2, in twice
_validate_twice_args(n)
File "demo.py", line 7, in _validate_twice_args
raise TypeError('n must be an int')
TypeError: n must be an int
エラーの場所は call ですがtwice(None)
、トレースバックは、エラーの責任者が気付いていないコードを参照しています (「_validate
誰?私はそれを呼び出したことがない!私はそれが何であるかさえ知りません!」)。 、「API の背後にある」べきコードを不必要に公開します。 のような「プライベート」ヘルパー関数がない場合でも、_validate_twice_args
不正な引数に応答して出力されるスタック トレースは、内部コードを不必要に公開し、エラーの場所を覆い隠します。
たとえば、 のコードをインライン化する_validate_twice_args
と、スタック トレースは次のようになります。
Traceback (most recent call last):
File "demo.py", line 10, in <module>
twice(None)
File "demo.py", line 3, in twice
raise TypeError('n must be an int')
TypeError: n must be an int
この種のエラーのスタック トレースがどのように表示されるかを理解するために、非常によく似たタイプのエラー ( のtwice()
代わりに呼び出しtwice(None)
が行われたもの) から発生したものを次に示しますが、制御が に渡される前に Python によって発生したものですtwice
。
Traceback (most recent call last):
File "demo.py", line 9, in <module>
twice()
TypeError: twice() takes exactly 1 argument (0 given)
この場合も、twice
無効な引数リストを使用した の呼び出しにエラーがあります。したがって、スタック トレースはエラーの場所を直接指しています (そして、エラーが最初に検出された基になる [おそらく C] コードの行ではありません。ありがたいことに)。これはあるべき姿です、IMO 1 .
スタックトレースの最後の行がバグのある呼び出しのソースコード行を参照するように変更するtwice_args
にはどうすればよいですか?_validate_twice_args
twice
1そのような場合にスタックトレースが何を言うべきかについての意見が私の意見と異なることは承知していますが、これらの哲学的な考慮事項はこのスレッドの主題ではありません。
編集:元の投稿の発言を強調しましたが、最初の 2 人の回答者は明らかに見落としていました。