Python中的異常處理raise案例介紹
0. 介紹
問(wèn)題1: 是否可以在程序的指定位置手動(dòng)拋出一個(gè)異常?
答案是肯定的,Python 允許我們?cè)诔绦蛑惺謩?dòng)設(shè)置異常,使用 raise 語(yǔ)句即可。
問(wèn)題2: 我們從來(lái)都是想方設(shè)法地讓程序正常運(yùn)行,為什么還要手動(dòng)設(shè)置異常呢?
首先要分清楚程序發(fā)生異常和程序執(zhí)行錯(cuò)誤,它們完全是兩碼事,程序由于錯(cuò)誤導(dǎo)致的運(yùn)行異常,是需要程序員想辦法解決的;但還有一些異常,是程序正常運(yùn)行的結(jié)果,比如用 raise 手動(dòng)引發(fā)的異常(比如1÷0沒(méi)有意義,程序沒(méi)有寫(xiě)錯(cuò),但是這樣運(yùn)算不合理,就是異常)。
raise 語(yǔ)句的基本語(yǔ)法格式為:
raise [exceptionName [(reason)]]
其中,用 [] 括起來(lái)的為可選參數(shù),其作用是指定拋出的異常名稱,以及異常信息的相關(guān)描述。
如果可選參數(shù)全部省略,則 raise 會(huì)把當(dāng)前錯(cuò)誤原樣拋出;如果僅省略 (reason),則在拋出異常時(shí),將不附帶任何的異常描述信息。
也就是說(shuō),raise 語(yǔ)句有如下三種常用的用法:
- raise:?jiǎn)为?dú)一個(gè) raise。該語(yǔ)句引發(fā)當(dāng)前上下文中捕獲的異常(比如在 except 塊中),或默認(rèn)引發(fā) RuntimeError 異常。
- raise 異常類名稱:raise 后帶一個(gè)異常類名稱,表示引發(fā)執(zhí)行類型的異常。
- raise 異常類名稱(描述信息):在引發(fā)指定類型的異常的同時(shí),附帶異常的描述信息。
代碼測(cè)試
>>> raise
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
raise
RuntimeError: No active exception to reraise>>> raise ZeroDivisionError
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
raise ZeroDivisionError
ZeroDivisionError
>>> raise ZeroDivisionError("除數(shù)不能為零")
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
raise ZeroDivisionError("除數(shù)不能為零")
ZeroDivisionError: 除數(shù)不能為零
1. raise 介紹(案例)
程序正常運(yùn)行的時(shí)候,根據(jù)需要,用 raise 手動(dòng)引發(fā)異常。
raise 語(yǔ)句引發(fā)的異常,通常用 try except(else finally)異常處理結(jié)構(gòu)來(lái)捕獲并進(jìn)行處理。例如:
try:
a = input("輸入一個(gè)數(shù):")
#判斷用戶輸入的是否為數(shù)字
if(not a.isdigit()):
raise ValueError("a 必須是數(shù)字")
except ValueError as e:
print("引發(fā)異常:", repr(e))
當(dāng)我們輸入字母 a ,程序運(yùn)行結(jié)果為:
runfile('E:/09-code/01-turbulence/test/test04.py', wdir='E:/09-code/01-turbulence/test')
輸入一個(gè)數(shù):>? a
引發(fā)異常: ValueError('a 必須是數(shù)字')
當(dāng)我們輸入數(shù)字 8,程序運(yùn)行結(jié)果為:
輸入一個(gè)數(shù):8
由上面示例可以看出,我們手動(dòng)讓程序引發(fā)異常,很多時(shí)候并不是為了讓其崩潰。
2. raise 不需要參數(shù)(案例)
這里重點(diǎn)關(guān)注位于 except 塊中的 raise
try:
a = input("輸入一個(gè)數(shù):")
if(not a.isdigit()):
raise ValueError("a 必須是數(shù)字")
except ValueError as e:
print("引發(fā)異常:", repr(e))
raise
由于在其之前我們已經(jīng)手動(dòng)引發(fā)了 ValueError 異常,因此這里當(dāng)再使用 raise 語(yǔ)句時(shí),它會(huì)再次引發(fā)一次。當(dāng)我們輸入字母 a ,程序執(zhí)行結(jié)果為:
In[2]: runfile('E:/09-code/01-turbulence/test/test04.py', wdir='E:/09-code/01-turbulence/test')
輸入一個(gè)數(shù):a
引發(fā)異常: ValueError('a 必須是數(shù)字',)
Traceback (most recent call last):
File "D:\python3.6\1.py", line 4, in <module>
raise ValueError("a 必須是數(shù)字")
ValueError: a 必須是數(shù)字這里重點(diǎn)關(guān)注位于 except 塊中的 raise,由于在其之前我們已經(jīng)手動(dòng)引發(fā)了 ValueError 異常,因此這里當(dāng)再使用 raise 語(yǔ)句時(shí),它會(huì)再次引發(fā)一次。
3. raise:?jiǎn)为?dú)一個(gè) raise(正常程序使用無(wú)參的 raise )
當(dāng)在沒(méi)有引發(fā)過(guò)異常的程序使用無(wú)參的 raise 語(yǔ)句時(shí),它默認(rèn)引發(fā)的是 RuntimeError 異常。例如:
try:
a = input("輸入一個(gè)數(shù):")
if(not a.isdigit()):
raise
except RuntimeError as e:
print("引發(fā)異常:", repr(e))當(dāng)我們輸入字母 a ,程序執(zhí)行結(jié)果為:
In[3]: runfile('E:/09-code/01-turbulence/test/test04.py', wdir='E:/09-code/01-turbulence/test')
輸入一個(gè)數(shù):>? a
引發(fā)異常: RuntimeError('No active exception to reraise')
4. 其它案例
4.1 案例1
def read_file(file, pattern):
try:
if file.endswith('rtd'):
data = pd.read_csv(file, skiprows=41, sep=r'\t')
elif file.endswith('csv'):
data = pd.read_csv(file)
else:
raise ValueError("Unknown file type")
data = extract_cols(data, pattern=pattern, file=file)
except Exception as e:
print(f"{os.path.basename(file).split('.')[0]}: {e}")
data = pd.DataFrame()
return data
4.2 案例2
def divide(a, b):
return a/b
try:
divide(1, 0)
except:
print("divide by 0")
else:
print("the code is no problem")
print("code after try catch,hello,world!")輸出結(jié)果
divide by 0
code after try catch,hello,world!
5. 處理流程
try: code #需要判斷是否會(huì)拋出異常的代碼,如果沒(méi)有異常處理,python會(huì)直接停止執(zhí)行程序 except: #這里會(huì)捕捉到上面代碼中的異常,并根據(jù)異常拋出異常處理信息 #except ExceptionName,args: #同時(shí)也可以接受異常名稱和參數(shù),針對(duì)不同形式的異常做處理 code #這里執(zhí)行異常處理的相關(guān)代碼,打印輸出等 else: #如果沒(méi)有異常則執(zhí)行else code #try部分被正常執(zhí)行后執(zhí)行的代碼 finally: code #退出try語(yǔ)句塊總會(huì)執(zhí)行的程序
可以看到,
- 這里的 else 是和 try-catch 連用的,并且 else 只在 try 中代碼沒(méi)有異常的情況下執(zhí)行,else 必須在 except 這句代碼存在的時(shí)候才能出現(xiàn)。
- finally 這個(gè)片段里面的代碼是肯定在最后執(zhí)行的,無(wú)論前面是否發(fā)生異常,最后總會(huì)執(zhí)行finally片段內(nèi)的代碼。
- 所以,正常的流程是:try 沒(méi)有發(fā)生錯(cuò)誤-》else 內(nèi)的代碼-》finally 中的代碼。
- 發(fā)生異常的流程是:try 中發(fā)生異常-》被 except 捕獲并執(zhí)行 except 片段中的代碼-》執(zhí)行 finally 中的代碼。
6. 顯示error位置
要在拋出異常時(shí)包含代碼所在的位置,可以使用Python的traceback模塊。這個(gè)模塊可以獲取異常發(fā)生時(shí)的堆棧信息,包括文件名和行號(hào)。
以下是一個(gè)示例代碼,展示了如何在捕獲異常時(shí)打印出詳細(xì)的錯(cuò)誤信息,包括代碼所在的位置:
import traceback
try:
# 假設(shè)這是可能會(huì)拋出異常的代碼
# 例如:result = 10 / 0 # 這將引發(fā)ZeroDivisionError
result = 10 / 0
except Exception as e:
# 獲取異常信息和堆棧跟蹤
tb = traceback.format_exc()
print(f"Error processing {filename}: {e}\nTraceback:\n{tb}")在這個(gè)示例中,traceback.format_exc()會(huì)返回一個(gè)字符串,其中包含了異常的詳細(xì)信息和堆棧跟蹤,包括引發(fā)異常的文件名和行號(hào)。這樣,就可以清楚地看到錯(cuò)誤發(fā)生的位置。??
錯(cuò)誤信息如下:
Error processing : division by zero
Traceback:
Traceback (most recent call last):
File "<ipython-input-5-6bef8f98af92>", line 6, in <module>
result = 10 / 0
ZeroDivisionError: division by zero
總結(jié)
也就是說(shuō),raise 語(yǔ)句有如下三種常用的用法:
1.raise:?jiǎn)为?dú)一個(gè) raise。該語(yǔ)句引發(fā)當(dāng)前上下文中捕獲的異常(比如在 except 塊中),或默認(rèn)引發(fā) RuntimeError 異常。
2.raise 異常類名稱:raise 后帶一個(gè)異常類名稱,表示引發(fā)執(zhí)行類型的異常。
3.raise 異常類名稱(描述信息):在引發(fā)指定類型的異常的同時(shí),附帶異常的描述信息。
參考鏈接:
鏈接1、
到此這篇關(guān)于Python中的異常處理raise案例介紹的文章就介紹到這了,更多相關(guān)python 異常處理raise內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python 信息同時(shí)輸出到控制臺(tái)與文件的實(shí)例講解
今天小編就為大家分享一篇python 信息同時(shí)輸出到控制臺(tái)與文件的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
關(guān)于Pycharm配置翻譯插件Translation報(bào)錯(cuò)更新TTK失敗不能使用的問(wèn)題
這篇文章主要介紹了關(guān)于Pycharm配置翻譯插件Translation報(bào)錯(cuò)更新TTK失敗不能使用的問(wèn)題,本文通過(guò)圖文并茂的形式給大家分享解決方案,需要的朋友可以參考下2022-04-04
深入理解Python中的 __new__ 和 __init__及區(qū)別介紹
這篇文章主要介紹了深入理解Python中的 __new__ 和 __init__及區(qū)別介紹,這兩個(gè)方法的主要區(qū)別在于:__new__ 負(fù)責(zé)對(duì)象的創(chuàng)建而 __init__ 負(fù)責(zé)對(duì)象的初始化。具體內(nèi)容詳情大家跟隨小編一起看看吧2018-09-09
把JSON數(shù)據(jù)格式轉(zhuǎn)換為Python的類對(duì)象方法詳解(兩種方法)
本文通過(guò)兩種方法給大家介紹了把JSON數(shù)據(jù)格式轉(zhuǎn)換為Python的類對(duì)象,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-06-06

