読者です 読者をやめる 読者になる 読者になる

Python用のデバッグマクロ的な関数(競プロ用)

その他

C++の競プロ用マクロっていろいろあるみたいなんですが、その中にこういうマクロがありました。
競技プログラミング特有の変な実装テク // ichyo.jp

#define debug(x) cout<<#x<<": "<<x<<endl

これって多分"変数名: 中身"っていうのを表示してくれるマクロだと思うんですよね。
例えば hoge = 12 って置いてたらdebug(hoge)で"hoge: 12"って表示してくれるみたいな。
こういうのあると便利だなあ、と思ったのでPythonでも似たような関数が作れないか少し調べてみました。

それで作ったのがこんな関数です

def debug(x, table):
    for name, val in table.items():
        if x is val:
            print('DEBUG:{} -> {}'.format(name, val), file=sys.stderr)
            return None

変数名を取得する方法が名前空間ってとこから探してくるみたいなやり方でできるみたいです、詳しくは以下
変数の変数名を文字列で取得する。 - Qiita
How to get a variable name as a string in Python? - Stack Overflow

出力オプションにfile=sys.stderrとつけていると標準エラー出力に結果を表示してくれるので、提出時にコメントアウトし忘れても一応安心です。
でもなんかでかいものを出力したりすると普通に実行速度が落ちるので基本的には提出時にはコメントアウトした方がいいと思います。

使い方ですが、例えばhogeの中身を知りたかったら

debug(hoge, locals())

と書きます。中身が数だろうが文字列だろうがリストだろうが辞書だろうがセットだろうが表示できます。

これでだいたい事足りますが欠点としては違う名前の変数が同じものを指している場合、どちらの変数名が表示されるか分からないってとこですかね……。
例えば

a = 1
b = 1
c = 1

ってなってるときに

debug(c, locals())

ってやると

DEBUG:a -> 1

とか

DEBUG:b -> 1

とか表示される可能性があります。
でもこの仕様で実用上困ることは無さそうなので今のところは放置しています。