python中捕捉的异常类型
如果在使用这种格式的话(except Exception as e:), 表示不过所有可能的错误异常
说明
例1:
try:
res = 10/0
except ZeroDivisionError :
print "Error:Divisor must not be zero!"
结果:
Error:Divisor must not be zero!
例2:
try:
res = 10/0
except ZeroDivisionError as e:
print "Error:Divisor must not be zero!"
print "error: %s" % e
结果:
Error:Divisor must not be zero!
error: integer division or modulo by zero
比较例1和例2,说明异常把报错信息传给了e,你可以再后面选择输入e。
异常中的else使用
try:
fd = open("hellojason.txt",'r')
except Exception as e:
print "an error occured: %s " % e
else:
for f in fd:
print f,
fd.close()
错误结果:
an error occured: [Errno 2] No such file or directory: 'hellojason.txt'
异常中的else表示:如果在try中语句执行没有检查到错误,则将执行else中的结果。还要注意的一点就是else一定要跟在except语句后面。
异常中的finally
try:
fd = open("hellojason.html",'r')
except Exception as e:
print "an error occured: %s " % e
else:
for f in fd:
print f,
finally:
fd.close()
finally语句在这里并不是用来捕捉异常的,而是finally提供一些代码,无论是否出现错误,都必须执行finally里面的代码。
with与上下文管理器
看个例子:
import sys
def test(filename):
with open(filename, 'r') as f:
sys.stdout.write(f.read())
print f.read()
if __name__ == '__main__':
print test("file.txt")
结果,报错:
in test
print f.read()
ValueError: I/O operation on closed file
解释:
with是一个控制流语句,跟if/for/while/try之类的是一类的,with可以用来简化try finally代码,看起来可以比try finally更清晰。
with obj 语句在控制流程进入和离开其后的相关代码中,允许对象obj管理所发生的事情。执行with obj语句时,它执行obj.__enter__()方法来指示正在进入一个新的上下文。当控制流离开该上下文的时候,它就会执行obj.__exit__(type, value, traceback)。
这里新引入了一个"上下文管理协议"context management protocol,实现方法是为一个类定义__enter__和__exit__两个函数。with expresion as variable的执行过程是,首先执行__enter__函数,它的返回值会赋给as后面的variable,想让它返回什么就返回什么,只要你知道怎么处理就可以了,如果不写as variable,返回值会被忽略。然后,开始执行with-block中的语句,不论成功失败(比如发生异常、错误,设置sys.exit()),在with-block执行完成后,会执行__exit__函数关闭打开的资源。
清楚了吧,所以使用with比使用try finally更加的便捷。
为了可以将我们自己的类来使用with语句,我们可以构建这样的类:
class test:
def __enter__(self):
print 'in enter'
def __exit__(self, *argvs):
print 'in exit'
Test_class = test()
with Test_class as a:
print 'in with'
print a
结果:
in enter
in with
None
in exit
看输出的结果,可以知道
1.先执行类里面的__enter__函数
2.然后把__enter__的返回值赋值给a
3.执行with中的语句
4.执行__exit__函数
在使用with语句来使用这些共享资源,那就更方便了,我们不用担心会因为某种原因而没有释放他。但并不是所有的对象都可以使用with语句,只有支持上下文管理协议(context management protocol)的对象才可以,那哪些对象支持该协议呢?如下表:
file
decimal.Context
thread.LockType
threading.Lock
threading.RLock
threading.Condition
threading.Semaphore
threading.BoundedSemaphore
raise 自定义抛出异常
raise [SomeException [, args [,traceback]]
第一个参数,SomeException必须是一个异常类,或异常类的实例
第二个参数是传递给SomeException的参数,必须是一个元组。这个参数用来传递关于这个异常的有用信息。
第三个参数traceback很少用,主要是用来提供一个跟中记录对象(traceback)
例:
try:
raise IOError,"io error is occurred"
except IOError as e:
print "an error: %s" % e
结果:
an error: io error is occurred
异常与sys模块
另一种获取异常信息的途径是通过sys模块中的exc_info()函数。该函数回返回一个三元组:(异常类,异常类的实例,跟中记录对象)
>>> try:
... 1/0
... except:
... import sys
... tuple = sys.exc_info()
...
>>> print tuple
(<type 'exceptions.ZeroDivisionError'>, ZeroDivisionError('integer division or modulo by zero',), <traceback object at 0x7f538a318b48>)
>>> for i in tuple:
... print i
...
<type 'exceptions.ZeroDivisionError'> #异常类
integer division or modulo by zero #异常类的实例
<traceback object at 0x7f538a318b48> #跟踪记录对象