Python中的异常(Exception)处理
異常
當你的程序出現例外情況時就會發生異常(Exception)。例如,當你想要讀取一個文件時,而那個文件卻不存在,怎么辦?又或者你在程序執行時不小心把它刪除了,怎么辦?這些通過使用異常來進行處理。
類似地,如果你的程序中出現了一些無效的語句該怎么辦?Python 將會對此進行處理,舉起(Raises)它的小手來告訴你哪里出現了一個錯誤(Error)。
錯誤
你可以想象一個簡單的?print?函數調用。如果我們把?print?誤拼成?Print?會怎樣?你會注意到它的首字母是大寫。在這一例子中,Python 會拋出(Raise)一個語法錯誤。
>>> Print("Hello World") Traceback (most recent call last):File "<stdin>", line 1, in <module> NameError: name 'Print' is not defined >>> print("Hello World") Hello World?
你會注意到一個?NameError?錯誤被拋出,同時 Python 還會打印出檢測到的錯誤發生的位置。這就是一個錯誤錯誤處理器(Error Handler)2?為這個錯誤所做的事情。
異常
我們將嘗試(Try)去讀取用戶的輸入內容。按下?[ctrl-d]?來看看會發生什么事情。
>>> s = input('Enter something --> ') Enter something --> Traceback (most recent call last):File "<stdin>", line 1, in <module> EOFError?
此處 Python 指出了一個稱作?EOFError?的錯誤,代表著它發現了一個文件結尾(End of File)符號(由?ctrl-d?實現)在不該出現的時候出現了。
處理異常
我們可以通過使用?try..except?來處理異常狀況。一般來說我們會把通常的語句放在 try 代碼塊中,將我們的錯誤處理器代碼放置在 except 代碼塊中。
案例(保存文?exceptions_handle.py):
try:text = input('Enter something --> ') except EOFError:print('Why did you do an EOF on me?') except KeyboardInterrupt:print('You cancelled the operation.') else:print('You entered {}'.format(text))?
輸出:
# Press ctrl + d $ python exceptions_handle.py Enter something --> Why did you do an EOF on me?# Press ctrl + c $ python exceptions_handle.py Enter something --> ^CYou cancelled the operation.$ python exceptions_handle.py Enter something --> No exceptions You entered No exceptions?
它是如何工作的
我們將所有可能引發異常或錯誤的語句放在?try?代碼塊中,并將相應的錯誤或異常的處理器(Handler)放在?except?子句或代碼塊中。except?子句可以處理某種特定的錯誤或異常,或者是一個在括號中列出的錯誤或異常。如果沒有提供錯誤或異常的名稱,它將處理所有錯誤與異常。
要注意到必須至少有一句?except?字句與每一句?try?字句相關聯。不然,有一個 try 代碼塊又有什么意義?
如果沒有任何錯誤或異常被處理,那么將調用 Python 默認處理器,它只會終端程序執行并打印出錯誤信息。我們已經在前面的章節里見過了這種處理方式。
你還可以擁有一個?else?子句與?try..except?代碼塊相關聯。else?子句將在沒有發生異常的時候執行。
在下一個案例中,我們還將了解如何獲取異常對象以便我們可以檢索其他信息。
拋出異常3
你可以通過?raise?語句來引發一次異常,具體方法是提供錯誤名或異常名以及要拋出(Thrown)異常的對象。
你能夠引發的錯誤或異常必須是直接或間接從屬于?Exception(異常) 類的python 派生類。
案例(保存為?exceptions_raise.py):
# encoding=UTF-8 class ShortInputException(Exception): '''一個由用戶定義的異常類''' def __init__(self, length, atleast): Exception.__init__(self)self.length = lengthself.atleast = atleast try:text = input('Enter something --> ') if len(text) < 3: raise ShortInputException(len(text), 3) # 其他工作能在此處繼續正常運行 except EOFError:print('Why did you do an EOF on me?') except ShortInputException as ex:print(('ShortInputException: The input was ' + '{0} long, expected at least {1}').format(ex.length, ex.atleast)) else:print('No exception was raised.')?
輸出:
$ python exceptions_raise.py Enter something --> a ShortInputException: The input was 1 long, expected at least 3$ python exceptions_raise.py Enter something --> abc No exception was raised.?
它是如何工作的
在本例中,我們創建了我們自己的異常類型。這一新的異常類型叫作?ShortInputException。它包含兩個字段——獲取給定輸入文本長度的?length,程序期望的最小長度?atleast。
在?except?子句中,我們提及了錯誤類,將該類存儲?as(為)?相應的錯誤名或異常名。這類似于函數調用中的形參與實參。在這個特殊的?except?子句中我們使用異常對象的?length?與?atleast?字段來向用戶打印一條合適的信息。
Try ... Finally
假設你正在你的讀取中讀取一份文件。你應該如何確保文件對象被正確關閉,無論是否會發生異常?這可以通過?finally?塊來完成。
保存該程序為?exceptions_finally.py:
import sys import timef = None try:f = open("poem.txt") # 我們常用的文件閱讀風格 while True:line = f.readline() if len(line) == 0: break print(line, end='')sys.stdout.flush()print("Press ctrl+c now") # 為了確保它能運行一段時間 time.sleep(2) except IOError:print("Could not find file poem.txt") except KeyboardInterrupt:print("!! You cancelled the reading from the file.") finally: if f:f.close()print("(Cleaning up: Closed the file)")?
輸出:
$ python exceptions_finally.py Programming is fun Press ctrl+c now ^C!! You cancelled the reading from the file. (Cleaning up: Closed the file)?
它是如何工作的
我們按照通常文件讀取進行操作,但是我們同時通過使用?time.sleep?函數任意在每打印一行后插入兩秒休眠,使得程序運行變得緩慢(在通常情況下 Python 運行得非常快速)。當程序在處在運行過過程中時,按下?ctrl + c?來中斷或取消程序。
你會注意到?KeyboardInterrupt?異常被拋出,爾后程序退出。不過,在程序退出之前,finally 子句得到執行,文件對象總會被關閉。
另外要注意到我們在?print?之后使用了?sys.stout.flush(),以便它能被立即打印到屏幕上。
with?語句
在?try?塊中獲取資源,然后在?finally?塊中釋放資源是一種常見的模式。因此,還有一個?with?語句使得這一過程可以以一種干凈的姿態得以完成。
保存為?exceptions_using_with.py:
with open("poem.txt") as f: for line in f:print(line, end='')?
它是如何工作的
程序輸出的內容應與上一個案例所呈現的相同。本例的不同之處在于我們使用的是?open?函數與?with?語句——我們將關閉文件的操作交由?with open?來自動完成。
在幕后發生的事情是有一項?with?語句所使用的協議(Protocol)。它會獲取由?open?語句返回的對象,在本案例中就是“thefile”。
+它總會在代碼塊開始之前調用?thefile.__enter__?函數,并且總會在代碼塊執行完畢之后調用?thefile.__exit__。
因此,我們在?finally?代碼塊中編寫的代碼應該格外留心?__exit__?方法的自動操作。這能夠幫助我們避免重復顯式使用?try..finally?語句。
有關Python教程中這話題的更多討論已經超出了本書所能涉及的范圍,因此請參考?PEP 343?來了解更加全面的解釋。
總結
我們已經討論了?try..except?和?try..finally?語句的用法。同時我們也已經看到了如何創建我們自己的python 異常類型,還有如何拋出異常。
接下來,我們將探索 Python 的標準庫。
?
轉載于:https://www.cnblogs.com/yuanrenxue/p/10670124.html
總結
以上是生活随笔為你收集整理的Python中的异常(Exception)处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringBoot_定制banner
- 下一篇: grid - 使用相同的名称命名网格线和