如果在使用这种格式的话(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。
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语句后面。
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里面的代码。
看个例子:
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 [SomeException [, args [,traceback]]
第二个参数是传递给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模块中的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> #跟踪记录对象