LoginSignup
14
13

More than 3 years have passed since last update.

print() を使う前に PySnooper

Last updated at Posted at 2019-04-26

前提: ログ出力のための 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行を元に戻すだけで元の挙動に戻ります。デコレータだと修正箇所が局所にとどまらないのと、同じ関数を呼び出している他のコードに影響が出るので、その意味でも実践で使いづらいんじゃないかなと思いました。

使い勝手がわかってきたらまた書きます。

14
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
13