[Python] traceback exception 내용 다듬기 Develop Tip

다음과 같은 간단한 파이썬 코드가 있습니다.

def d():
return 1/0

def c():
return d()

def b():
return c()

def a():
return b()

print a()

이것을 실행하면,

Traceback (most recent call last):
  File "/home/toor/workpy/xtmController/test/except_test.py", line 28, in <module>
    print a()
  File "/home/toor/workpy/xtmController/test/except_test.py", line 16, in a
    return b()
  File "/home/toor/workpy/xtmController/test/except_test.py", line 13, in b
    return c()
  File "/home/toor/workpy/xtmController/test/except_test.py", line 10, in c
    return d()
  File "/home/toor/workpy/xtmController/test/except_test.py", line 7, in d
    return 1/0
ZeroDivisionError: integer division or modulo by zero

이런 흔한 오류 메시지가 나타납니다.
이 메시지가 눈에 잘 와 닿지는 않습니다.
또한 코딩 스택에 익숙한 개발자에게는 most recent call last 보다는 most recent call first 를 선호 합니다.

위와 같은 traceback 메시지는 
traceback.format_exc() 로 얻을 수 있습니다.


이것을 다음과 같이 정리를 해 보았습니다.

import traceback

def getTracebackStr():
lines = traceback.format_exc().strip().split('\n')
rl = [lines[-1]]
lines = lines[1:-1]
lines.reverse()
for i in xrange(0,len(lines),2):
rl.append('^\t%s at %s' % (lines[i].strip(),lines[i+1].strip()))
return '\n'.join(rl)

def d():
return 1/0
def c():
return d()
def b():
return c()
def a():
return b()

try:
print a()
except Exception, e:
print getTracebackStr()

그러면 결과가,

ZeroDivisionError: integer division or modulo by zero
^ return 1/0 at File "/home/toor/workpy/xtmController/test/except_test.py", line 16, in d
^ return d() at File "/home/toor/workpy/xtmController/test/except_test.py", line 19, in c
^ return c() at File "/home/toor/workpy/xtmController/test/except_test.py", line 22, in b
^ return b() at File "/home/toor/workpy/xtmController/test/except_test.py", line 25, in a
^ print a() at File "/home/toor/workpy/xtmController/test/except_test.py", line 28, in <module>

와 같이 좀 더 보기 쉽게 정리가 되었습니다.

setup.py 로 설치를 한 다음 동일한 모듈을 호출하면 메시지 내용이 틀려집니다.
이를 보완하기 위하여 다음과 같이 함수를 수정해 봅니다.

###############################################################################
def getTracebackStr():
lines = traceback.format_exc().strip().split('\n')
rl = [lines[-1]]
lines = lines[1:-1]
lines.reverse()
nstr = ''
for i in range(len(lines)):
line = lines[i].strip()
if line.startswith('File "'):
eles = lines[i].strip().split('"')
basename = os.path.basename(eles[1])
lastdir = os.path.basename(os.path.dirname(eles[1]))
eles[1] = '%s/%s' % (lastdir,basename)
rl.append('^\t%s %s' % (nstr,'"'.join(eles)))
nstr = ''
else:
nstr += line
return '\n'.join(rl)


ZeroDivisionError: integer division or modulo by zero
^ return 1/0 at File "test/except_test.py", line 16, in d
^ return d() at File "test/except_test.py", line 19, in c
^ return c() at File "test/except_test.py", line 22, in b
^ return b() at File "test/except_test.py", line 25, in a
^ print a() at File "test/except_test.py", line 28, in <module>


어느분게는 도움이 되셨기를...

핑백

  • 지훈현서 : [C#] 파이썬의 TraceBack 2013-10-30 10:39:46 #

    ... 그것을 출력해주어야 어디서 발생한 예외인지 쉽게찾을 수 있습니다. (파이썬에서는 traceback 이라는 type이 가지고 있고,</a><a href="http://mcchae.egloos.com/11018564">그것을 잘 표현하는 것을 지난번에 포스팅한 적이 있습니다.) C#의 예외 객체는 StackTrace 라는 문자열에 그 ... more

덧글

댓글 입력 영역

구글애드텍스트