LoginSignup
7
3

More than 3 years have passed since last update.

【Python】エラー発生時に関数内の変数を知りたい!

Last updated at Posted at 2021-01-06

はじめに

皆さんはデバッグをどのように行っていますか?
デバッガとか使ってするのが一般的でしょうか、Pdbとか?

それはさておき、エラー発生時ってとりあえず関数内のローカル変数を見たくなりますよね。
でも”ローカルな”変数ですので、関数外からは見られず結局printに走る、あるあるだと思います。

今回は、せめてエラー発生時の変数だけでもまとめて出力できたら…と思いデコレータを作成しました。

つくったもの

def raise_locals(f):
    import sys, traceback
    def wrapper(*args, **kwargs):
        try:
            return f(*args, **kwargs)
        except Exception:
            exc_type, exc_value, exc_traceback = sys.exc_info()
            ext = traceback.StackSummary.extract(traceback.walk_tb(exc_traceback), capture_locals=True)
            locals_ = ext[-1].locals
            if locals_:
                print('{' + ', '.join([f"'{k}': {v}" for k, v in locals_.items()]) + '}')
            raise
    return wrapper

構造としては、実行してみてエラーが発生したらtracebackを通じてローカル変数を拾ってくるって感じです。
では使ってみましょう。

@raise_locals
def f(x):
    a = x
    b = 1 / a
    a = 1

f(0)
out
{'x': 0, 'a': 0}
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-137-16e1baa342f5> in <module>
      5     a = 1
      6 
----> 7 f(0)

<ipython-input-136-f595b8b52afb> in wrapper(*args, **kwargs)
      3     def wrapper(*args, **kwargs):
      4         try:
----> 5             f(*args, **kwargs)
      6         except Exception as e:
      7                 exc_type, exc_value, exc_traceback = sys.exc_info()

<ipython-input-137-16e1baa342f5> in f(x)
      2 def f(x):
      3     a = x
----> 4     b = 1 / a
      5     a = 1
      6 

ZeroDivisionError: division by zero

いつものエラー文の前にエラー発生時のローカル変数が表示されていますね。

def f(x):
    a = x
    b = 1 / a

@raise_locals
def main():
    f(x=0)

if __name__=='__main__':
    main()

一番親となる関数につけておけば、どこでエラーが発生してもそのエラーが発生した関数のローカル変数を見ることができます。

7
3
1

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
7
3