Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
[python] icecream ライブラリのサンプル (debug, print, ic, configureOutput)
"""
icecream ライブラリのサンプル
REFERENCES::
https://github.com/gruns/icecream
"""
import collections
import contextlib as ctx
import datetime
from icecream import ic
def go():
"""処理を実行します"""
###############################################
# icecream
# ---------------------------------------------
# icecream はデバッグ時によく利用する print 出力を
# もっと便利にしてくれるライブラリ。
# 使い方については、github の README.md に記載されて
# いるので、だいたい分かる。
# 以下、基本的な使い方をメモしたもの。
###############################################
#
# (1) print(f'hoge={hoge}') の代わり
# ---------------------------------------------
# よくデバッグ時に上記のように出力入れたりするが
# icecream だと以下のように書ける
# ic(hoge)
# これだけで、"ic| hoge: hoge"と出力してくれる
#
hello = 'world'
ic(hello) # ic| hello: 'world'
# リストの場合
l01 = list(range(10))
ic(l01[-1]) # ic| l01[-1]: 9
# 辞書の場合
d01 = dict(zip(['apple', 'banana'], [100, 200]))
ic(d01['apple']) # ic| d01['apple']: 100
# 集合の場合
s01 = set(range(10))
ic(s01.pop()) # ic| s01.pop(): 0
# 独自オブジェクトの場合
Data1 = collections.namedtuple('Data1', ['x', 'y'])
dat1 = Data1(100, 200)
ic(dat1) # ic| dat1: Data1(x=100, y=200)
#
# (2) print(1) のような通過確認用ログの代わり
# ---------------------------------------------
# よくデバッグ時に上記のように「この場所を通ったか?」の
# 確認用出力を入れたりするが
# icecream だと以下のように書ける
# ic()
# これだけで、"ic| icecream_sample.py:10"と出力してくれる
#
def debug_print():
print(0)
# 何か処理....
print(1)
# 何か処理....
print(2)
def debug_ic():
ic()
# 何か処理....
ic()
# 何か処理....
ic()
debug_print()
debug_ic()
# ただし、この状態ではソースファイルと行番号しか出せない
# 「コネクション確保」とかみたいな補助情報も出力したい場合は
# 以下のように includeContext を True に設定する
def debug_ic2():
ic.includeContext = True
conn = None
ic(conn)
# 何か処理
conn = dat1
ic(conn)
ic.includeContext = False
debug_ic2()
# 以下のように with で一時的なスイッチできるようにした方が使いやすいかも
@ctx.contextmanager
def context_on():
old = ic.includeContext
ic.includeContext = True
yield
ic.includeContext = old
def debug_ic3():
with context_on():
conn = None
ic(conn)
# 何か処理
conn = dat1
ic(conn)
ic()
debug_ic3()
#
# (3) ic() は引数の値をそのまま返してくれる
# ---------------------------------------------
# なので、関数の引数に渡すついでにログ出力なども出来る
#
def tekito(x, y):
return x + y
x = 10
y = 20
tekito(ic(x), ic(y))
#
# (4) ic.disable()/enable()で有効無効を切り替え可能
# ---------------------------------------------
#
@ctx.contextmanager
def ic_off():
ic.disable()
try:
yield
finally:
ic.enable()
with ic_off():
ic('これは出力されない')
#
# (5) prefix(ic|って出てる部分)を変更可能
# ---------------------------------------------
# ic.configureOutput(prefix=xx) で変更できる
# prefix=xxの部分には関数も指定可能。
# 現在のprefixは、ic.prefixで取得できる
#
def yyyymmddhhmiss():
d = datetime.datetime.now()
s = d.strftime('%Y/%m/%d %H:%M:%S')
return f'{s} |> '
@ctx.contextmanager
def datetime_prefix_on():
old = ic.prefix
try:
ic.configureOutput(prefix=yyyymmddhhmiss)
yield
finally:
ic.prefix = old
with datetime_prefix_on():
ic()
ic(dat1)
ic()
#
# ic.configureOutput()には、他にも
# 出力処理を指定できる outputFunction や
# 引数の値を文字列にする際に呼ばれる argToStringFunction が
# 指定できる
#
# 割愛
# https://github.com/gruns/icecream 参照
if __name__ == '__main__':
go()
@devlights
Copy link
Author

devlights commented Mar 27, 2018

結果は以下のような感じになる

ic| hello: 'world'
ic| l01[-1]: 9
ic| d01['apple']: 100
ic| s01.pop(): 0
ic| dat1: Data1(x=100, y=200)
0
1
2
ic| icecream_sample.py:73 in debug_ic()
ic| icecream_sample.py:75 in debug_ic()
ic| icecream_sample.py:77 in debug_ic()
ic| icecream_sample.py:88 in debug_ic2()- conn: None
ic| icecream_sample.py:91 in debug_ic2()- conn: Data1(x=100, y=200)
ic| icecream_sample.py:107 in debug_ic3()- conn: None
ic| icecream_sample.py:110 in debug_ic3()- conn: Data1(x=100, y=200)
ic| icecream_sample.py:111 in debug_ic3()
ic| x: 10
ic| y: 20
2018/03/27 14:35:45 |> icecream_sample.py:165 in go()
2018/03/27 14:35:45 |> dat1: Data1(x=100, y=200)
2018/03/27 14:35:45 |> icecream_sample.py:167 in go()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment