首页 > 代码库 > python 学习笔记 6 -- 异常处理

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

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

那么如果你是在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 --> 123
Haha,you are so right!
long@zhouyl:/tmp$ python try_excepy.py
Enter something -->                         # 这里是输入Enter,没有异常提示
Haha,you are so right!
long@zhouyl:/tmp$ python try_excepy.py
Enter something --> ^C                      # 输入Ctrl+C退出,提示的为最后未加类型的except
Some error/exception occurred.
long@zhouyl:/tmp$ python try_excepy.py
Enter 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 = atleast
try:                                            # try 接着可能发生错误的语句
    s = raw_input(‘Enter something --> ‘)
    if len(s) < 3:                              # 假如输入字符串数的小于3,使用raise引发定义的ShortInputException异常。
        raise ShortInputException(len(s), 3)
    # Other work can continue as usual here
except 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 3
long@zhouyl:/tmp$ python raise.py
Enter something -->                     # 没输入字符!仍然raise异常
ShortInputException: The input was of length 0,     was expecting at least 3
long@zhouyl:/tmp$ python raise.py
Enter something -->                     # Ctrl+D引发except EOFError异常
Why did you do an EOF on me?
long@zhouyl:/tmp$ python raise.py
Enter 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 os
import 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.name
else:
	print "No exception was raised,Now Opening the file %s ..." % file_name
	try:
		f = file(file_name)     # 读模式打开
		while True:             # 以while循环运行其中的读文件,一行一行读直到break
			line = f.readline() # 读一行
			if len(line) == 0:  # 假如读到EOF就break
			    break
			time.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.py
Input the file you want to open:    file        # 输入一个不存在的文件名,引发我们自定义的异常
self defined Exception is raised ,the file "file" not exist
long@zhouyl:/tmp/test$ python python_execpt.py
Input the file you want to open:    poem.txt    
File exist ,everything goes well
No 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秒
KeyboardInterrupt
long@zhouyl:/tmp/test$ python python_execpt.py
Input the file you want to open:    poem.txt
File exist ,everything goes well
No 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处的except
Cleaning up...closed the file                       # 继续调用finally中的关闭文件操作
long@zhouyl:/tmp/test$