Debug是学习代码的必经之路,代码运行时出现错误很常见,这个时候就需要我们拥有找到错误并解决错误的能力,那么try...except将必不可少。

首先上干货:

import traceback
try:
print("我是函数主体")
except Exception as e:
traceback.print_exc()
print("出现异常来这里")
else:
print("没异常就继续")
finally:
print("最终都会来这里")

一、对上述代码进行拆分

1、else:若try中的函数没有发生异常,将执行else下的代码。

else 必须放在所有的except之后。

2、finally:无论有无异常发生,都将执行finally中的代码。

以上二者都不是必须的,所以极简的模式为:

import traceback
try:
xxxx
except Exception as e:
traceback.print_exc()

二、输出异常信息

1、print e:这个语句可谓是新手必备,它可以输出错误,但是效果嘛...看例子吧:

try:

a = 10/0
except Exception as e:
print(e)

输出结果:

division by zero

这个结果让人摸不着头脑,division by zero!到底是哪里division by zero了?

2、traceback.print_exc() :打印详细的异常信息。(神器来了)

import traceback

try:

a = 10/0
except Exception as e:
traceback.print_exc()

输出结果:

Traceback (most recent call last):

File "xxxx\test1.py", line 4, in

a = 10/0

ZeroDivisionError: division by zero

第四行的xxx中division by zero,多么详细的信息啊,有时候,debug就是这么简单!

三、sys & traceback

1、sys:说一说其中的exc_info()方法。

exc_info() 方法会将当前的异常信息以元组的形式返回,该元组中包含 3 个元素,分别为 type、value 和 traceback,它们的含义分别是:type:异常类型的名称,它是 BaseException 的子类

value:捕获到的异常实例。

traceback:是一个 traceback 对象。

上例子:

import sys
try:
a = 10/0
except Exception as e:
print(sys.exc_info())

输出结果:

(, ZeroDivisionError('division by zero'), )

可看出发生了一个ZeroDivisionError类型的错误,错误实例为:division by zero,然后还有一个traceback 对象。

可使用traceback 包中的print_tb方法读取traceback对象,并打印出来:

import sys
import traceback
try:
a = 10/0
except Exception as e:
traceback_obj = sys.exc_info()[2]
traceback.print_tb(traceback_obj)

输出结果:

File "xxxx\test1.py", line 5, in

a = 10/0

可见,traceback 对象内包含的就是详细的异常信息。

2、traceback 包提供了一整套接口用于提取,格式化和打印Python程序的stack traces信息。

上面说道整个异常的传播轨迹都存储在traceback对象中,可使用traceback包中的方法来读取,不过老是取对象,读一下也略繁琐,然后traceback干脆糖了一波:

上面说的:traceback.print_tb()方法只读取traceback对象的内容。

而:traceback.print_exc()方法更高级,读取type,value以及traceback对象的全部内容,更厉害的是它直接把sys.exc_info()嵌在了内部,无需手动获取,可以看一下源码:

def print_exc(limit=None, file=None, chain=True):
"""Shorthand for 'print_exception(*sys.exc_info(), limit, file)'."""
print_exception(*sys.exc_info(), limit=limit, file=file, chain=chain)

ok,然后对比一下二者输出的异常信息:

traceback.print_tb()
File "xxxx\test1.py", line 5, in 
a = 10/0
traceback.print_exc()
Traceback (most recent call last):
File "xxxx\test1.py", line 4, in 
a = 10/0
ZeroDivisionError: division by zero

四、福利环节:输出到log

仔细阅读源码的同学已经发现:

def print_exc(limit=None, file=None, chain=True)

通过传递file参数,可以将异常信息直接打印到文件中。

当然还有一种方式,尤其是使用logging包的同学:

import logging
logger = logging.getLogger(__name__)
try:
a = 10/0
except Exception as e:
logger.error("Error:",exc_info=True)
logger.error("Error:",exc_info=True) 可直接将详细的信息打印到日志文件中,方便日后的debug.