1. Python中的异常栈跟踪

Python,在2.x中,异常对象可以是任何对象,异常对象和异常栈是分开的。
python中用于处理异常栈的模块是traceback模块,它提供了print_exception、format_exception等输出异常栈等常用的工具函数。

 def func(a, b):
return a / b
if __name__ == '__main__':
import sys
import traceback
try:
func(1, 0)
except Exception as e:
print "print exc"
traceback.print_exc(file=sys.stdout)

输出结果:

 print exc
Traceback (most recent call last):
File "./teststacktrace.py", line 7, in <module>
func(1, 0)
File "./teststacktrace.py", line 2, in func
return a / b

其实traceback.print_exc()函数只是traceback.print_exception()函数的一个简写形式,而它们获取异常相关的数据都是通过sys.exc_info()函数得到的。

 def func(a, b):
return a / b
if __name__ == '__main__':
import sys
import traceback
try:
func(1, 0)
except Exception as e:
print "print_exception()"
exc_type, exc_value, exc_tb = sys.exc_info()
print 'the exc type is:', exc_type
print 'the exc value is:', exc_value
print 'the exc tb is:', exc_tb
traceback.print_exception(exc_type, exc_value, exc_tb)

输出结果:

 print_exception()
the exc type is: <type 'exceptions.ZeroDivisionError'>
the exc value is: integer division or modulo by zero
the exc tb is: <traceback object at 0x104e7d4d0>
Traceback (most recent call last):
File "./teststacktrace.py", line 7, in <module>
func(1, 0)
File "./teststacktrace.py", line 2, in func
return a / b
ZeroDivisionError: integer division or modulo by zero

sys.exc_info()返回的值是一个元组,其中第一个元素,exc_type是异常的对象类型,exc_value是异常的值,exc_tb是一个 traceback对象,对象中包含出错的行数、位置等数据。然后通过print_exception函数对这些异常数据进行整理输出。

traceback模块提供了extract_tb函数来更加详细的解释traceback对象所包含的数据:

 def func(a, b):
return a / b
if __name__ == '__main__':
import sys
import traceback
try:
func(1, 0)
except:
_, _, exc_tb = sys.exc_info()
for filename, linenum, funcname, source in traceback.extract_tb(exc_tb):
print "%-23s:%s '%s' in %s()" % (filename, linenum, source, funcname)

输出结果:

 samchimac:tracebacktest samchi$ python ./teststacktrace.py
./teststacktrace.py :7 'func(1, 0)' in <module>()
./teststacktrace.py :2 'return a / b' in func()

2. 使用cgitb来简化异常调试

如果平时开发喜欢基于log的方式来调试,那么可能经常去做这样的事情,在log里面发现异常之后,因为信息不足,那么会再去额外加一些debug log来把相关变量的值输出。调试完毕之后再把这些debug log去掉。其实没必要这么麻烦,Python库中提供了cgitb模块来帮助做这些事情,它能够输出异常上下文所有相关变量的信息,不必每次自己再去手动加debug log。

cgitb的使用简单的不能想象:

 def func(a, b):
return a / b
if __name__ == '__main__':
import cgitb
cgitb.enable(format='text')
import sys
import traceback
func(1, 0)

运行之后就会得到详细的数据:

 A problem occurred in a Python script.  Here is the sequence of
function calls leading up to the error, in the order they occurred. /Users/samchi/Documents/workspace/tracebacktest/teststacktrace.py in <module>()
4 import cgitb
5 cgitb.enable(format='text')
6 import sys
7 import traceback
8 func(1, 0)
func = <function func> /Users/samchi/Documents/workspace/tracebacktest/teststacktrace.py in func(a=1, b=0)
2 return a / b
3 if __name__ == '__main__':
4 import cgitb
5 cgitb.enable(format='text')
6 import sys
a = 1
b = 0

完全不必再去log.debug("a=%d" % a)了,个人感觉cgitb在线上环境不适合使用,适合在开发的过程中进行调试,非常的方便。

也许你会问,cgitb为什么会这么屌?能获取这么详细的出错信息?其实它的工作原理同它的使用方式一样的简单,它只是覆盖了默认的sys.excepthook函数,sys.excepthook是一个默认的全局异常拦截器,可以尝试去自行对它修改:

 def func(a, b):
return a / b
def my_exception_handler(exc_type, exc_value, exc_tb):
print "i caught the exception:", exc_type
while exc_tb:
print "the line no:", exc_tb.tb_lineno
print "the frame locals:", exc_tb.tb_frame.f_locals
exc_tb = exc_tb.tb_next if __name__ == '__main__':
import sys
sys.excepthook = my_exception_handler
import traceback
func(1, 0)

输出结果:

 i caught the exception: <type 'exceptions.ZeroDivisionError'>
the line no: 14
the frame locals: {'my_exception_handler': <function my_exception_handler at 0x100e04aa0>, '__builtins__': <module '__builtin__' (built-in)>, '__file__': './teststacktrace.py', 'traceback': <module 'traceback' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/traceback.pyc'>, '__package__': None, 'sys': <module 'sys' (built-in)>, 'func': <function func at 0x100e04320>, '__name__': '__main__', '__doc__': None}
the line no: 2
the frame locals: {'a': 1, 'b': 0}

3. 使用logging模块来记录异常

在使用Java的时候,用log4j记录异常很简单,只要把Exception对象传递给log.error方法就可以了,但是在Python中就不行了,如果直接传递异常对象给log.error,那么只会在log里面出现一行异常对象的值。

在Python中正确的记录Log方式应该是这样的:

 logging.exception(ex)
logging.error(ex, exc_info=1) # 指名输出栈踪迹, logging.exception的内部也是包了一层此做法
logging.critical(ex, exc_info=1) # 更加严重的错误级别

转自:http://my.oschina.net/chihz/blog/180573

Python traceback【转】的更多相关文章

  1. [转] Python Traceback详解

    追莫名其妙的bugs利器-mark- 转自:https://www.jianshu.com/p/a8cb5375171a   Python Traceback详解   刚接触Python的时候,简单的 ...

  2. Python traceback 模块,追踪错误

    Python traceback 模块,追踪错误 import traceback try: your code except: traceback.print_exc()

  3. Python traceback的优雅处理

    刚接触Python的时候,简单的异常处理已经可以帮助我们解决大多数问题,但是随着逐渐地深入,我们会发现有很多情况下简单的异常处理已经无法解决问题了,如下代码,单纯的打印异常所能提供的信息会非常有限. ...

  4. Python traceback 异常处理

    刚接触Python的时候,简单的异常处理已经可以帮助我们解决大多数问题,但是随着逐渐地深入,我们会发现有很多情况下简单的异常处理已经无法解决问题了,如下代码,单纯的打印异常所能提供的信息会非常有限. ...

  5. Python traceback 模块, 打印异常信息

    Python感觉是模仿Java, 到处都需要加try..catch.... 这里记录一下用法,方便后续使用. # -*- coding:utf-8 -*- import os import loggi ...

  6. python traceback

    1. Python中的异常栈跟踪 之前在做Java的时候,异常对象默认就包含stacktrace相关的信息,通过异常对象的相关方法printStackTrace()和getStackTrace()等方 ...

  7. python traceback学习(转)

    1. Python中的异常栈跟踪 之前在做Java的时候,异常对象默认就包含stacktrace相关的信息,通过异常对象的相关方法printStackTrace()和getStackTrace()等方 ...

  8. Python traceback模块简单使用

    Python中的traceback模块被用于跟踪异常返回信息,可以在logging中记录下traceback. traceback.format_exc() 获取异常为字符串,保存到日志文件 try: ...

  9. python traceback 变量值

    import sys import traceback import cgitb def handleException(excType, excValue, trace): print 'error ...

随机推荐

  1. MySQL 拷贝数据库表方式备份,还原后提示 table xxx '' doesn`t exist

    MySQL很强大,支持直接拷贝数据库文件快速备份,那数据库文件在哪里呢? 打开MySQL的配置文件 my.ini,找到 datadir 节点,如 datadir="D:/Program Fi ...

  2. Mac Pro 软件安装/个性化配置 汇总

    苹果产品维修 一.Spotlight 搜索程序和文档 Spotlight是最最常用的东西, 类似Windows开始菜单中的搜索.  可以用来搜索文档,也可以搜索本机的程序, 这样可以快速启动. 点击右 ...

  3. 妈妈再也不用担心别人问我是否真正用过redis了

    1. Memcache与Redis的区别 1.1. 存储方式不同 1.2. 数据支持类型 1.3. 使用底层模型不同 2. Redis支持的数据类型 3. Redis的回收策略 4. Redis小命令 ...

  4. DirectAccess

    DirectAccess Direct Access 称为直接访问,它是Windows 7(企业版或者更高级版本)和Windows Server 2008 R2中的一项新功能.凭借这个功能,外网的用户 ...

  5. [转]Ubantu vmware tools 安装

    https://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&external ...

  6. System Error Codes

    很明显,以下的文字来自微软MSDN 链接http://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx M ...

  7. JdbcTemplate中queryForObject的EmptyResultDataAccessException问题

    在使用Spring提供的JdbcTemplate中名为queryForObject API进行数据库查询时有时会抛出如下异常提示息,org.springframework.dao.EmptyResul ...

  8. ASP.NET MVC随想录——锋利的KATANA

    正如上篇文章所述那样,OWIN在Web Server与Web Application之间定义了一套规范(Specs),意在解耦Web Server与Web Application,从而推进跨平台的实现 ...

  9. IIS跳转html页面自动识别是PC端还是手机端

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. Web前端发展前景及就业方向

    Web前端发展前景及就业方向 HTML5技术已经日趋成熟 Html5是移动互联网前端的主流开发语言,目前还没有一个前端的开发语言能取代 html5的位置,所以说,无论你是做手机网站还是在手机app应用 ...