前提: ログ出力のための print と import logging はやめてほしい
どの行を実行しているかをとりあえず print()
でばらまくのは論外として、デバッグ時に logger.debug()
ぶちまくと言うのも不本意です。
そこでちょっとおもしろいライブラリを教えてもらったので共有します
とりあえず使ってみます。フィボナッチの実装面は目をつぶってください。
def fib(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
fib1 = 1
fib2 = 0
for i in range(2, n):
fib = fib1 + fib2
fib2 = fib1
fib1 = fib
return fib
if __name__ == '__main__':
import pysnooper
fib = pysnooper.snoop()(fib)
print(fib(5))
$ python /tmp/fib.py
Starting var:.. n = 5
09:27:24.164992 call 1 def fib(n):
09:27:24.165538 line 2 if n == 0:
09:27:24.165567 line 4 elif n == 1:
09:27:24.165589 line 7 fib1 = 1
New var:....... fib1 = 1
09:27:24.165650 line 8 fib2 = 0
New var:....... fib2 = 0
09:27:24.165695 line 9 for i in range(2, n):
New var:....... i = 2
09:27:24.165755 line 10 fib = fib1 + fib2
New var:....... fib = 1
09:27:24.165814 line 11 fib2 = fib1
Modified var:.. fib2 = 1
09:27:24.165845 line 12 fib1 = fib
09:27:24.165894 line 9 for i in range(2, n):
Modified var:.. i = 3
09:27:24.165952 line 10 fib = fib1 + fib2
Modified var:.. fib = 2
09:27:24.165995 line 11 fib2 = fib1
09:27:24.166032 line 12 fib1 = fib
Modified var:.. fib1 = 2
09:27:24.166064 line 9 for i in range(2, n):
Modified var:.. i = 4
09:27:24.166121 line 10 fib = fib1 + fib2
Modified var:.. fib = 3
09:27:24.166178 line 11 fib2 = fib1
Modified var:.. fib2 = 2
09:27:24.166234 line 12 fib1 = fib
Modified var:.. fib1 = 3
09:27:24.166290 line 9 for i in range(2, n):
09:27:24.166311 line 13 return fib
09:27:24.166333 return 13 return fib
Return value:.. 3
3
write()
を実装しているStream風味オブジェクトに吐き出せるようです。Logger
と連携させる簡便な方法は今の所ないようです(PRしろ)。
本家の例のようにデコレータ @pysnooper.snoop()
を関数に付けてもよいのですが、恒久的に使うのでなければ上記のように単に関数をラップして使う方が取り外しが楽で良いんじゃないかなと思ったので本例ではそうしています。
実際に開発している際には(バグが見つかったとして)
if __name__ == '__main__':
print(fib(5))
を
if __name__ == '__main__':
import pysnooper
print(pysnooper.snoop()(fib)(5))
とするだけで全ダンプが得られ、また同2行を元に戻すだけで元の挙動に戻ります。デコレータだと修正箇所が局所にとどまらないのと、同じ関数を呼び出している他のコードに影響が出るので、その意味でも実践で使いづらいんじゃないかなと思いました。
使い勝手がわかってきたらまた書きます。