python 学习笔记 6 -- 异常处理

时间:2022-02-12 00:04:48

当你的程序中出现某些 异常的 状况的时候,异常就发生了。例如,当你想要读某个文件的时候,而那个文件不存在。或者在程序运行的时候,你不小心把它删除了。

那么如果你是在IDE中运行,一个错误发生,异常会被打引出来,这便是未处理异常;当异常发生时,如果没有代码去关注和处理它,这些异常会传给置在Python中的缺省处理,他会输出一些调试信息并且终止运行。如果是在IDE中,这不是什么大事,但是如果是Python程序运行中的异常,它会导致整个程序终止,对于这些情况可以使用异常来处理。


1.try..except

我们可以使用try..except语句来处理异常。我们把通常的语句放在try-块中,而把我们的错误处理语句放在except-块中。

注:在try...except块可以有一个else子句,就像if语句,如果在try中没有异常引发,然后else子句就执行!!!

eg. 

#!/usr/bin/python# -*- coding: utf-8 -*- 

import sys
try:            # 把所有可能引发错误的语句放在try块中,然后在except从句/块中处理所有的错误和异常。
    s = raw_input('Enter something --> ')
except EOFError:    # except从句可以专门处理单一的错误或异常,或者一组包括在圆括号内的错误/异常。EOFError的错误,这个错误基本上意味着它发现一个不期望的 文件尾(由Ctrl-d表示)
    print '\nWhy did you do an EOF on me?'
    sys.exit()      # 退出程序
except:             # 如果没有给出错误或异常的名称,它会处理*所有的*错误和异常。
    print '\nSome error/exception occurred.'
else:               # 没有引发错误就执行此句
    print "Haha,you are so right!"

上面的例子中,我们只指明了一个EOFError错误(使用Ctrl+D异常退出),在最后还使用了一个不指定类型的except(用来解决全部的错误),所以运行结果如下:

 

long@zhouyl:/tmp/test$ python try_excepy.py # 输入正常信息,会执行else语句中的,没有异常提醒Enter something --> 123Haha,you are so right!long@zhouyl:/tmp$ python try_excepy.pyEnter something -->                         # 这里是输入Enter,没有异常提示Haha,you are so right!long@zhouyl:/tmp$ python try_excepy.pyEnter something --> ^C                      # 输入Ctrl+C退出,提示的为最后未加类型的exceptSome error/exception occurred.long@zhouyl:/tmp$ python try_excepy.pyEnter something -->                         # 输入Ctrl+D退出,提示为except EOFError后面的部分Why did you do an EOF on me?

 

2.引发异常

你可以使用raise语句 引发 异常。你还得指明错误/异常的名称和伴随异常 触发的 异常对象。你可以引发的错误或异常应该分别是一个Error或Exception类的直接或间接导出类。

eg.

#!/usr/bin/python# -*- coding: utf-8 -*-class ShortInputException(Exception):           # ShortInputException为我们自己定义的异常类型    '''A user-defined exception class.'''       # doc string ,可以使用ShortInputException.__doc__ 打印这个信息    def __init__(self, length, atleast):        # 定义初始化        Exception.__init__(self)        self.length = length        self.atleast = atleasttry:                                            # try 接着可能发生错误的语句    s = raw_input('Enter something --> ')    if len(s) < 3:                              # 假如输入字符串数的小于3,使用raise引发定义的ShortInputException异常。        raise ShortInputException(len(s), 3)    # Other work can continue as usual hereexcept EOFError:                                # 上面说到过,EOFError是不正常的文件尾(由Ctrl-d引发)    print '\nWhy did you do an EOF on me?'except ShortInputException, x:                  # raise的异常在这处理,此处为打印一些一场信息    print 'ShortInputException: The input was of length %d, \    was expecting at least %d' % (x.length, x.atleast)else:    print 'No exception was raised.'


上面的程序已经大概介绍了怎么运行,raise怎么引发我们自己定义的异常,运行效果如下:

 

long@zhouyl:/tmp$ python raise.py  Enter something --> ab                  # 输入两个字符,不满足3个字符,raise引发我们自己定义的ShortInputException异常ShortInputException: The input was of length 2,     was expecting at least 3long@zhouyl:/tmp$ python raise.pyEnter something -->                     # 没输入字符!仍然raise异常ShortInputException: The input was of length 0,     was expecting at least 3long@zhouyl:/tmp$ python raise.pyEnter something -->                     # Ctrl+D引发except EOFError异常Why did you do an EOF on me?long@zhouyl:/tmp$ python raise.pyEnter something --> abcdefg             # 输入7个字符,运行正常!No exception was raised.

3.try..finally

假如你在读一个文件的时候,希望在无论异常发生与否的情况下都关闭文件,该怎么做呢?这可以使用finally块来完成。
注:在一个try块下,你可以同时使用except从句和finally块。如果你要同时使用它们的话,需要把一个嵌入另外一个。

eg.

#!/usr/bin/python# -*- coding: utf-8 -*-import time     # 应用time库,下面使用到了其中的sleep函数try:            # 下面接的是可能出错的语句,但是不管出错不出错,finally中的都要执行    f = file('poem.txt')    # 读模式打开    while True:             # 以while循环运行其中的读文件,一行一行读直到break        line = f.readline() # 读一行        if len(line) == 0:  # 假如读到EOF就break            break        time.sleep(2)       # sleep 2秒        print line,         # 加了逗号,不会自动换行finally:    f.close()    print 'Cleaning up...closed the file'


上面已经说过,如果try部分运行异常了仍然会运行finally部分,所以我们在读文件时每读一行添加了两秒睡眠,如果我们在读过程中中断,效果如下:

 long@zhouyl:/tmp$ python finally.py

This is the python poem

using for txt read

do you like me?

^CCleaning up...closed the file         # 在此,我们使用Ctrl+D中断运行,finnaly中的关闭文件仍然运行

Traceback (most recent call last):

  File "finally.py", line 11, in <module>

    time.sleep(2)       # sleep 2秒

 

4. 一个综合小例子

当然,我们可以将几种异常处理综合在一起,做出个比较强大的异常捕获方法!

一般情况下,我们不会直接将try...execpt和try...finally一起使用,如果需要使用则需要使用嵌套!

eg.

#!/usr/bin/python# -*- coding: utf-8 -*-import osimport time     # 应用time库,下面使用到了其中的sleep函数class FileExistException(Exception):           # 我们自己定义的异常类型    '''A user-defined exception class for test the file exist'''       # doc string    def __init__(self, name):        # 定义初始化        Exception.__init__(self)        self.name = name# 脚本从这开始哦~try:            # 下面接的是可能出错的语句,但是不管出错不出错,finally中的都要执行file_name = raw_input("Input the file you want to open:\t")if os.path.exists(file_name) == False:    # 假如文件不存在,引发FileExistException异常。raise FileExistException(file_name)else:print "File exist ,everything goes well"except EOFError:                                # EOFError是不正常的文件尾(由Ctrl-d引发)print '\nWhy did you do an EOF on me?'except FileExistException,x:                  # raise的异常在这处理,此处为打印一些一场信息print "self defined Exception is raised ,the file \"%s\" not exist " %  x.nameelse:print "No exception was raised,Now Opening the file %s ..." % file_nametry:f = file(file_name)     # 读模式打开while True:             # 以while循环运行其中的读文件,一行一行读直到breakline = f.readline() # 读一行if len(line) == 0:  # 假如读到EOF就break    breaktime.sleep(2)       # sleep 2秒print line,         # 加了逗号,不会自动换行print "\nHello ,Now I will show a jump ~~~\n"try:# 又嵌套一层,不要太迷糊,我在这主要就是想多玩玩几层嵌套!f.seek(-128,2)# 重新跳转到倒数128个字节上,可能引发异常! (可以根据文件大小多测试几个数值)# 如果不引发异常,就在下一行中读取倒数128字节的文件内容# 如果引发异常,我们可以学习下这几层嵌套会如何执行。我们会发现它先执行except块再执行finally块f.read()except IOError:print "seek file error,may your file is not large enough"except IOError:# 前面已经通过我们自己定义的异常检查了文件是否存在,但是在打开时以及阅读时仍然可能引发异常print "open file error ,maybe your file is not so good!"finally:# 为了文件安全,如果引发异常就在此执行关闭文件操作!    f.close()    print 'Cleaning up...closed the file'

运行结果与分析如下:

 

long@zhouyl:/tmp/test$ python python_execpt.pyInput the file you want to open:    file        # 输入一个不存在的文件名,引发我们自定义的异常self defined Exception is raised ,the file "file" not existlong@zhouyl:/tmp/test$ python python_execpt.pyInput the file you want to open:    poem.txt    File exist ,everything goes wellNo exception was raised,Now Opening the file poem.txt ...This is the python poem   using for txt read   do you like me?  whatever  I like myself   ^CCleaning up...closed the file             # 在此,我们使用Ctrl+D中断运行,finnaly中的关闭文件仍然运行Traceback (most recent call last):  File "python_execpt.py", line 31, in <module>    time.sleep(2)       # sleep 2秒KeyboardInterruptlong@zhouyl:/tmp/test$ python python_execpt.pyInput the file you want to open:    poem.txtFile exist ,everything goes wellNo exception was raised,Now Opening the file poem.txt ...This is the python poem   using for txt read   do you like me?  whatever  I like myself   I'm selfconfidence Hello ,Now I will show a jump ~~~       seek file error,may your file is not large enough   # 引发seek处的exceptCleaning up...closed the file                       # 继续调用finally中的关闭文件操作long@zhouyl:/tmp/test$