發(fā)布于:2021-01-22 14:50:30
0
145
0
Python程序一旦遇到錯(cuò)誤就會(huì)終止。在Python中,錯(cuò)誤可以是語(yǔ)法錯(cuò)誤或異常。在本文中,您將看到什么是異常以及它與語(yǔ)法錯(cuò)誤的區(qū)別。之后,您將學(xué)習(xí)如何提出異常和作出斷言。然后,您將演示try-and-except塊。
異常與語(yǔ)法錯(cuò)誤
語(yǔ)法錯(cuò)誤發(fā)生在解析器檢測(cè)到錯(cuò)誤語(yǔ)句時(shí)。觀察以下示例:
>>> print( 0 / 0 ))
File "", line 1
print( 0 / 0 ))
^
SyntaxError: invalid syntax
箭頭指示解析器在哪里遇到語(yǔ)法錯(cuò)誤。在這個(gè)例子中,有一個(gè)括號(hào)太多。刪除它并再次運(yùn)行代碼:
>>> print( 0 / 0)
Traceback (most recent call last):
File "", line 1, inZeroDivisionError: integer division or modulo by zero
這次,您遇到了一個(gè)異常錯(cuò)誤。每當(dāng)語(yǔ)法正確的Python代碼導(dǎo)致錯(cuò)誤時(shí),就會(huì)發(fā)生這種類(lèi)型的錯(cuò)誤。消息的最后一行指示遇到的異常錯(cuò)誤類(lèi)型。
Python沒(méi)有顯示消息exception error
,而是詳細(xì)說(shuō)明遇到的異常錯(cuò)誤類(lèi)型。在本例中,它是一個(gè)ZeroDivisionError
。Python提供了各種內(nèi)置異常以及創(chuàng)建自定義異常的可能性。
引發(fā)異常
如果條件發(fā)生,我們可以使用raise
引發(fā)異常。該語(yǔ)句可以用一個(gè)自定義異常來(lái)補(bǔ)充。
如果您想在使用raise
發(fā)生某個(gè)條件時(shí)拋出錯(cuò)誤,您可以這樣做:
x = 10
if x > 5:
raise Exception('x should not exceed 5. The value of x was: {}'.format(x))
運(yùn)行此代碼時(shí),輸出如下所示:
Traceback (most recent call last):
File "", line 4, inException: x should not exceed 5. The value of x was: 10
程序停止并在屏幕上顯示我們的異常,提供出錯(cuò)的線(xiàn)索。
AssertionError異常
除了等待程序中途崩潰之外,您還可以先用Python進(jìn)行斷言。我們知道滿(mǎn)足某個(gè)條件。如果這個(gè)條件是True
,那就太好了!程序可以繼續(xù)。如果條件是False
,您可以讓程序拋出一個(gè)AssertionError
異常。
看看下面的示例,其中斷言代碼將在Linux系統(tǒng)上執(zhí)行:
import sys
assert ('linux' in sys.platform), "This code runs on Linux only."
如果您在Linux機(jī)器上運(yùn)行此代碼,斷言通過(guò)。如果要在Windows計(jì)算機(jī)上運(yùn)行此代碼,斷言的結(jié)果將是False
,結(jié)果如下:
Traceback (most recent call last):
File "<input>", line 2, in <module>
AssertionError: This code runs on Linux only.
在本例中,拋出AssertionError
異常是程序最不愿意做的事情。該計(jì)劃將停止,不再繼續(xù)。如果那不是你想要的呢?
try
and except
Block: Handling ExceptionsPython中的try
andexcept
塊用于捕獲和處理異常。Python將try
語(yǔ)句之后的代碼作為程序的“正?!辈糠謭?zhí)行。except
語(yǔ)句之后的代碼是程序?qū)ι弦?/span>try
條款中所有異常的響應(yīng)。
如您先前所見(jiàn),當(dāng)語(yǔ)法正確的代碼遇到錯(cuò)誤時(shí),Python將引發(fā)異常錯(cuò)誤。如果未處理,此異常錯(cuò)誤將使程序崩潰。該except
子句確定您的程序如何響應(yīng)異常。
以下功能可以幫助您了解try
和except
阻止:
def linux_interaction():
assert ('linux' in sys.platform), "Function can only run on Linux systems."
print('Doing something.')
將linux_interaction()
只能在Linux系統(tǒng)上運(yùn)行。如果您在Linux以外的其他操作系統(tǒng)上調(diào)用assert
in,此函數(shù)中的in將拋出AssertionError
異常。
您可以try
使用以下代碼為該函數(shù)指定a :
try:
linux_interaction()
except:
pass
您在此處處理錯(cuò)誤的方法是發(fā)出pass
。
你什么都沒(méi)有 這里的好處是程序沒(méi)有崩潰。但是,很高興看到每當(dāng)您運(yùn)行代碼時(shí)是否發(fā)生某種類(lèi)型的異常。為此,您可以將更pass
改為會(huì)產(chǎn)生信息的消息,例如:
try:
linux_interaction()
except:
print('Linux function was not executed')
在Windows計(jì)算機(jī)上執(zhí)行以下代碼:
Linux function was not executed
當(dāng)運(yùn)行此函數(shù)的程序中發(fā)生異常時(shí),該程序?qū)⒗^續(xù)運(yùn)行并通知您該函數(shù)調(diào)用未成功的事實(shí)。
您沒(méi)有看到的是由于函數(shù)調(diào)用而引發(fā)的錯(cuò)誤類(lèi)型。為了確切地了解出了什么問(wèn)題,您需要捕獲函數(shù)引發(fā)的錯(cuò)誤。
以下代碼是一個(gè)示例,您在其中捕獲AssertionError
并將該消息輸出到屏幕:
try:
linux_interaction()
except AssertionError as error:
print(error)
print('The linux_interaction() function was not executed')
在Windows計(jì)算機(jī)上運(yùn)行此功能將輸出以下內(nèi)容:
Function can only run on Linux systems.
The linux_interaction() function was not executed
第一條消息是AssertionError
,通知您該功能只能在Linux計(jì)算機(jī)上執(zhí)行。第二條消息告訴您未執(zhí)行的功能。
在上一個(gè)示例中,您調(diào)用了一個(gè)自己編寫(xiě)的函數(shù)。執(zhí)行該功能時(shí),您捕獲了AssertionError
異常并將其打印到屏幕上。
這是打開(kāi)文件并使用內(nèi)置異常的另一個(gè)示例:
try:
with open('file.log') as file:
read_data = file.read()
except:
print('Could not open file.log')
如果file.log不存在,則此代碼塊將輸出以下內(nèi)容:
Could not open file.log
這是一條信息,我們的程序仍將繼續(xù)運(yùn)行。在Python文檔中,您可以看到這里可以使用許多內(nèi)置的異常。該頁(yè)面上描述的一種異常如下:
Exception
FileNotFoundError
在請(qǐng)求文件或目錄但不存在時(shí)引發(fā)。對(duì)應(yīng)于errno ENOENT。
要捕獲這種類(lèi)型的異常并將其打印到屏幕上,可以使用以下代碼:
try:
with open('file.log') as file:
read_data = file.read()
except FileNotFoundError as fnf_error:
print(fnf_error)
在這種情況下,如果file.log不存在,則輸出為以下內(nèi)容:
[Errno 2] No such file or directory: 'file.log'
您的try
子句中可以有多個(gè)函數(shù)調(diào)用,并且可以預(yù)期會(huì)捕獲各種異常。這里要注意的是,try
子句中的代碼將在遇到異常后立即停止。
警告:捕獲會(huì)Exception隱藏所有錯(cuò)誤,甚至是完全意外的錯(cuò)誤。這就是為什么您應(yīng)該避免except在Python程序中使用裸子句的原因。相反,您將要引用要捕獲和處理的特定異常類(lèi)。您可以在本教程中詳細(xì)了解為什么這是個(gè)好主意。
看下面的代碼。在這里,您首先調(diào)用該linux_interaction()
函數(shù),然后嘗試打開(kāi)一個(gè)文件:
try:
linux_interaction()
with open('file.log') as file:
read_data = file.read()
except FileNotFoundError as fnf_error:
print(fnf_error)
except AssertionError as error:
print(error)
print('Linux linux_interaction() function was not executed')
如果該文件不存在,則在Windows計(jì)算機(jī)上運(yùn)行此代碼將輸出以下內(nèi)容:
Function can only run on Linux systems.
Linux linux_interaction() function was not executed
在該try
子句中,您立即遇到異常,而未到達(dá)嘗試打開(kāi)file.log的部分。現(xiàn)在看一下在Linux機(jī)器上運(yùn)行代碼時(shí)會(huì)發(fā)生什么:
[Errno 2] No such file or directory: 'file.log'
以下是關(guān)鍵要點(diǎn):
一個(gè)try條款執(zhí)行,直到在遇到第一個(gè)異常點(diǎn)。
在except子句或異常處理程序中,您可以確定程序如何響應(yīng)異常。
您可以預(yù)期多個(gè)異常,并區(qū)分程序應(yīng)如何應(yīng)對(duì)它們。
避免使用裸except子句。
使用finally
想象一下,在執(zhí)行代碼后,您總是需要執(zhí)行某種操作來(lái)清理。Python允許您使用finally
子句來(lái)執(zhí)行此操作。
查看以下示例:
try:
linux_interaction()
except AssertionError as error:
print(error)
else:
try:
with open('file.log') as file:
read_data = file.read()
except FileNotFoundError as fnf_error:
print(fnf_error)
finally:
print('Cleaning up, irrespective of any exceptions.')
在前面的代碼中,finally
子句中的所有內(nèi)容都將被執(zhí)行。如果在try
或else
子句中遇到異常,則無(wú)所謂。在Windows計(jì)算機(jī)上運(yùn)行以前的代碼將輸出以下內(nèi)容:
Function can only run on Linux systems.
Cleaning up, irrespective of any exceptions.
總結(jié)
在了解了語(yǔ)法錯(cuò)誤和異常之間的區(qū)別之后,您了解了在Python中引發(fā)、捕獲和處理異常的各種方法。在本文中,您看到了以下選項(xiàng):
raise
允許您隨時(shí)拋出異常。
assert
允許您驗(yàn)證是否滿(mǎn)足某個(gè)條件,如果不滿(mǎn)足則拋出異常。
在try
子句中,在遇到異常之前,將執(zhí)行所有語(yǔ)句。
except
用于捕獲和處理在try子句中遇到的異常。
else
允許您編寫(xiě)僅在try子句中未遇到異常時(shí)才應(yīng)運(yùn)行的代碼節(jié)。
finally
允許您執(zhí)行應(yīng)該始終運(yùn)行的代碼部分,無(wú)論是否有任何以前遇到的異常。
作者介紹
熱門(mén)博客推薦