Python實(shí)用指南:異常處理

每個(gè)程序員的夢(mèng)想都是編寫(xiě)一個(gè)可以平穩(wěn)運(yùn)行的程序,然而通常情況并非如此,我們的程序經(jīng)常會(huì)遇到錯(cuò)誤,一旦出現(xiàn)錯(cuò)誤,代碼的執(zhí)行就會(huì)停止。
意外的情況或條件可能會(huì)導(dǎo)致錯(cuò)誤。Python 將這些情況視為異常,并根據(jù)異常的類(lèi)型引發(fā)不同類(lèi)型的錯(cuò)誤。
ValueError、 TypeError、 AttributeError 和 SyntaxError 是這些異常的一些示例。好消息是 Python 還提供了處理異常的方法。
考慮下面的代碼,它要求用戶(hù)輸入一個(gè)數(shù)字并打印該數(shù)字的平方。
a = int(input("Please enter a number: "))print(f'{a} squared is {a*a}')
只要輸入是一個(gè)數(shù)字,它就可以正常工作。然而,如果用戶(hù)輸入一個(gè)字符串,python 將引發(fā)一個(gè) ValueError:

我們可以在代碼中實(shí)現(xiàn)一個(gè) try-except 塊來(lái)更好地處理這個(gè)異常。例如,我們可以向用戶(hù)返回一個(gè)更簡(jiǎn)單的錯(cuò)誤消息,或者請(qǐng)求他們提供另一個(gè)輸入。
try:a = int(input("Please enter a number: "))print(f'{a} squared is {a*a}')except:print("Wrong input type! You must enter a number!")
在上述情況下,代碼會(huì)更清楚地告知用戶(hù)有關(guān)錯(cuò)誤的信息。
如果由于 try 塊中的代碼引發(fā)了異常,則執(zhí)行將繼續(xù)使用 except 塊中的語(yǔ)句。因此將由程序員決定如何處理異常。
普通的 try-except 塊將捕獲任何類(lèi)型的錯(cuò)誤。但是,我們可以更具體一些。例如,我們可能只對(duì)特定類(lèi)型的錯(cuò)誤感興趣,或者希望以不同的方式處理不同類(lèi)型的錯(cuò)誤。
可以用 except 語(yǔ)句指定錯(cuò)誤類(lèi)型。考慮下面的代碼,它要求用戶(hù)從列表中輸入一個(gè)數(shù)字。然后,它根據(jù)輸入從字典返回一個(gè)名稱(chēng)。
dict_a = {1:'Max', 2:'Ashley', 3:'John'}number = int(input(f'Pick a number from the list: {list(dict_a.keys())}'))
如果用戶(hù)輸入一個(gè)不在給定列表中的數(shù)字,我們將得到一個(gè) KeyError。如果輸入不是一個(gè)數(shù)字,我們將得到一個(gè) ValueError。我們可以使用兩個(gè)語(yǔ)句來(lái)處理這兩種情況。
try:dict_a = {1:'Max', 2:'Ashley', 3:'John'}number = int(input(f'Pick a number from the list:{list(dict_a.keys())}'))print(dict_a[number])except KeyError:print(f'{number} is not in the list')except ValueError:print('You must enter a number!')

Python 還允許引發(fā)自己的異常。它類(lèi)似于自定義默認(rèn)異常。Raise 關(guān)鍵字和錯(cuò)誤類(lèi)型可以用于創(chuàng)建自己的異常。
try:a = int(input("Please enter a number: "))print(f'{a} squared is {a*a}')except:raise ValueError("You must enter a number!")
下面是非數(shù)字輸入情況下的錯(cuò)誤消息。
ValueError: You must enter a number!讓我們?cè)倥e一個(gè)例子,說(shuō)明如何在函數(shù)中使用 try-except 塊。
函數(shù)的作用是: 返回?cái)?shù)字列表的平均值。
a = [1, 2, 3]def avg_value(lst):avg = sum(lst) / len(lst)return avgprint(avg_value(a))2
如果我們向這個(gè)函數(shù)傳遞一個(gè)空列表,它將給出一個(gè) ZeroDivisionError,因?yàn)榭樟斜淼拈L(zhǎng)度為零。
我們可以在函數(shù)中實(shí)現(xiàn)一個(gè) try-except 塊來(lái)處理此異常。
def avg_value(lst):try:avg = sum(lst) / len(lst)return avgexcept:print('Warning: Empty list')return 0
對(duì)于空列表,函數(shù)將打印一個(gè)警告并返回0。
a = []print(avg_value(a))Warning: Empty list0
Try 和 except 塊用于處理異常。assert 用于確保條件符合函數(shù)的需求。
如果 assert 為 false,則函數(shù)不會(huì)繼續(xù)。因此,assert 可以作為防御性編程的一個(gè)例子,確保一切都按照預(yù)期進(jìn)行。
讓我們?cè)?av_value 函數(shù)中實(shí)現(xiàn) assert,確保列表不是空的。
def avg_value(lst):assert not len(lst) == 0, 'No values'avg = sum(lst) / len(lst)return avg
如果列表的長(zhǎng)度為零,則函數(shù)立即終止,否則,函數(shù)將繼續(xù)運(yùn)行直到結(jié)束。
如果 assert 語(yǔ)句中的條件為 false,則會(huì)引發(fā) AssertionError:
a = []print(avg_value(a))AssertionError: No values
assert 對(duì)于發(fā)現(xiàn)代碼中的錯(cuò)誤非常有用,因此,它們可以用來(lái)支持測(cè)試。
總結(jié)
我們已經(jīng)介紹了如何在代碼中實(shí)現(xiàn) try,except 和 assert。這在許多情況下都很有用,為程序員提供了對(duì)代碼的更多控制和監(jiān)督,使得他們能很好地發(fā)現(xiàn)和處理異常。
個(gè)人微信(如果沒(méi)有備注不拉群!) 請(qǐng)注明:地區(qū)+學(xué)校/企業(yè)+研究方向+昵稱(chēng)
下載1:何愷明頂會(huì)分享
在「AI算法與圖像處理」公眾號(hào)后臺(tái)回復(fù):何愷明,即可下載。總共有6份PDF,涉及 ResNet、Mask RCNN等經(jīng)典工作的總結(jié)分析
下載2:終身受益的編程指南:Google編程風(fēng)格指南
在「AI算法與圖像處理」公眾號(hào)后臺(tái)回復(fù):c++,即可下載。歷經(jīng)十年考驗(yàn),最權(quán)威的編程規(guī)范!
下載3 CVPR2020 在「AI算法與圖像處理」公眾號(hào)后臺(tái)回復(fù):CVPR2020,即可下載1467篇CVPR 2020論文
覺(jué)得不錯(cuò)就點(diǎn)亮在看吧

