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$ 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章