How do you guys debug?
Is it common to use a debugger or something like Pdb
?
Aside from that, when an error occurs, you want to see the local variables in the function for the time being.
However, since it is a "local" variable, it cannot be seen from outside the function and eventually runs to print
.
This time, I created a decorator, hoping that at least the variables at the time of the error could be output together.
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
The structure is like picking up a local variable through traceback if you try to run it and an error occurs. Let's use it.
@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
The local variable at the time of the error is displayed before the usual error statement.
def f(x):
a = x
b = 1 / a
@raise_locals
def main():
f(x=0)
if __name__=='__main__':
main()
If you attach it to the parent function, you can see the local variable of the function where the error occurred no matter where the error occurred.
Recommended Posts