def test(): try: print "try" return "RETURN" finally: print "finally" print test()
结果:
try
finally
RETURN
即使你在try中直接return了,finally还是会被执行的
http://www.cnblogs.com/klchang/p/4635040.html
异常信息的获取对于程序的调试非常重要,可以有助于快速定位有错误程序语句的位置。下面介绍几种python中获取异常信息的方法,这里获取异常(Exception)信息采用try...except...程序结构。如下所示
try: ... except Exception, e: ...
1、str(e)
返回字符串类型,只给出异常信息,不包括异常信息的类型,如1/0的异常信息
'integer division or modulo by zero'
2、repr(e)
给出较全的异常信息,包括异常信息的类型,如1/0的异常信息
"ZeroDivisionError('integer division or modulo by zero',)"
3、e.message
获得的信息同str(e)
4、采用traceback模块
需要导入traceback模块,此时获取的信息最全,与python命令行运行程序出现错误信息一致。使用traceback.print_exc()打印异常信息到标准错误,就像没有获取一样,或者使用traceback.format_exc()将同样的输出获取为字符串。你可以向这些函数传递各种各样的参数来限制输出,或者重新打印到像文件类型的对象。
import traceback print '########################################################' print "1/0 Exception Info" print '---------------------------------------------------------' try: 1/0 except Exception, e: print 'str(Exception):\t', str(Exception) print 'str(e):\t\t', str(e) print 'repr(e):\t', repr(e) print 'e.message:\t', e.message print 'traceback.print_exc():'; traceback.print_exc() print 'traceback.format_exc():\n%s' % traceback.format_exc() print '########################################################' print '\n########################################################' print "i = int('a') Exception Info" print '---------------------------------------------------------' try: i = int('a') except Exception, e: print 'str(Exception):\t', str(Exception) print 'str(e):\t\t', str(e) print 'repr(e):\t', repr(e) print 'e.message:\t', e.message print 'traceback.print_exc():'; traceback.print_exc() print 'traceback.format_exc():\n%s' % traceback.format_exc() print '########################################################'
http://www.runoob.com/python/python-exceptions.html
异常名称 | 描述 |
---|---|
BaseException | 所有异常的基类 |
Exception | 常规错误的基类 |
一般情况下,在Python无法正常处理程序时就会发生一个异常。
异常是Python对象,表示一个错误。
当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。
try:
<语句> #运行别的代码
except <名字>:
<语句> #如果在try部份引发了'name'异常
except <名字>,<数据>:
<语句> #如果引发了'name'异常,获得附加的数据
else:
<语句> #如果没有异常发生
#!/usr/bin/python
# -*- coding: UTF-8 -*-
try:
fh = open("testfile", "w")
fh.write("这是一个测试文件,用于测试异常!!")
except IOError:
print "Error: 没有找到文件或读取文件失败"
else:
print "内容写入文件成功"
fh.close()
可以不带任何异常类型使用except,如下实例:
try:
正常的操作
......................
except:
发生异常,执行这块代码
......................
else:
如果没有异常执行这块代码
以上方式try-except语句捕获所有发生的异常。
也可以使用相同的except语句来处理多个异常信息,如下所示:
try:
正常的操作
......................
except(Exception1[, Exception2[,...ExceptionN]]]):
发生以上多个异常中的一个,执行这块代码
......................
else:
如果没有异常执行这块代码
try-finally 语句无论是否发生异常都将执行最后的代码。
python中try/except/else/finally语句的完整格式如下所示:
Exception A handle
if no exception,get here
print("finally")
异常的参数
一个异常可以带上参数,可作为输出的异常信息参数。
你可以通过except语句来捕获异常的参数,如下所示:
try:
正常的操作
......................
except ExceptionType, Argument:
你可以在这输出 Argument 的值...
变量接收的异常值通常包含在异常的语句中。在元组的表单中变量可以接收一个或者多个值。
元组通常包含错误字符串,错误数字,错误位置。
Python2
try: print (1/0) except ZeroDivisionError, err: # , 加原因参数名称 print ('Exception: ', err)
Python3
try: print (1/0) except ZeroDivisionError as err: # as 加原因参数名称 print ('Exception: ', err)
触发异常
我们可以使用raise语句自己触发异常
raise语法格式如下:
raise [Exception [, args [, traceback]]]
语句中Exception是异常的类型(例如,NameError)参数是一个异常参数值。该参数是可选的,如果不提供,异常的参数是"None"。
最后一个参数是可选的(在实践中很少使用),如果存在,是跟踪异常对象。
一个异常可以是一个字符串,类或对象。
def functionName( level ): if level < 1: raise Exception("Invalid level!", level) # 触发异常后,后面的代码就不会再执行
注意:为了能够捕获异常,"except"语句必须有用相同的异常来抛出类对象或者字符串。
例如我们捕获以上异常,"except"语句如下所示:
try:
正常逻辑
except "Invalid level!":
触发自定义异常
else:
其余代码
4.引发异常
raise [exception[,data]]
在Python中,要想引发异常,最简单的形式就是输入关键字raise,后跟要引发的异常的名称。
异常名称标识出具体的类:Python异常是那些类的对象。执行raise语句时,Python会创建指定的异常类的一个对象。 (跟c++一样)
raise语句还可指定对异常对象进行初始化的参数。为此,请在异常类的名称后添加一个逗号以及指定的参数(或者由参数构成的一个元组)。
例:
try:
raise MyError #自己抛出一个异常, 抛出一个类类型,python会创建该类类型的一个对象
except MyError:
print 'a error'
raise ValueError, ’invalid argument’ #抛出一个类类型,同时指定构造函数的参数
捕捉到的内容为:
type = VauleError
message = invalid argument
用户自定义异常
通过创建一个新的异常类,程序可以命名它们自己的异常。异常应该是典型的继承自Exception类,通过直接或间接的方式。
以下为与RuntimeError相关的实例,实例中创建了一个类,基类为RuntimeError,用于在异常触发时输出更多的信息。
在try语句块中,用户自定义的异常后执行except块语句,变量 e 是用于创建Networkerror类的实例。
class Networkerror(RuntimeError):
def __init__(self, arg):
self.args = arg
在你定义以上类后,你可以触发该异常,如下所示:
try:
raise Networkerror("Bad hostname")
except Networkerror,e:
print e.args
========================================
try...
try: print('try...') r = 10 / 0 print('result:', r) except ZeroDivisionError as e: //e是ZeroDivisionError 类型的一个对象
print('except:', e) finally: print('finally...') print('END')
输出:
except: division by zero finally... END
当我们认为某些代码可能会出错时,就可以用try
来运行这段代码,如果执行出错,则后续代码不会继续执行,而是直接跳转至错误处理代码,即except
语句块,执行完except
后,如果有finally
语句块,则执行finally
语句块(无论是否发生了异常),至此,执行完毕。
try: print('try...') r = 10 / int('2') print('result:', r) except ValueError as e: print('ValueError:', e) except ZeroDivisionError as e: print('ZeroDivisionError:', e) else: print('no error!') finally: print('finally...') print('END')
Python的错误其实也是class,所有的错误类型都继承自BaseException
抛出错误
因为错误是class,捕获一个错误就是捕获到该class的一个实例。因此,错误并不是凭空产生的,而是有意创建并抛出的。Python的内置函数会抛出很多类型的错误,我们自己编写的函数也可以抛出错误。
如果要抛出错误,首先根据需要,可以定义一个错误的class,选择好继承关系,然后,用raise
语句抛出一个错误的实例:
# err_raise.py
class FooError(ValueError):
pass
def foo(s):
n = int(s)
if n==0:
raise FooError('invalid value: %s' % s)
return 10 / n
foo('0')
def foo(s):
n = int(s)
assert n != 0, 'n is zero!'
return 10 / n
def main():
foo('0')
程序中如果到处充斥着assert
,和print()
相比也好不到哪去。不过,启动Python解释器时可以用-O
参数来关闭assert, 关闭后,你可以把所有的assert
语句当成pass
来看。
logging 模块
import logging logging.basicConfig(level=logging.INFO)
记录信息的级别,有debug
,info
,warning
,error
等几个级别
pdb调试
-m module-name
Searches sys.path for the named module and runs the corresponding .py file as a script.
$ python3 -m pdb err.py
pdb.set_trace()
这个方法也是用pdb,但是不需要单步执行,我们只需要import pdb
,然后,在可能出错的地方放一个pdb.set_trace()
,就可以设置一个断点。运行代码,程序会自动在pdb.set_trace()
暂停并进入pdb调试环境。
单元测试,文档测试