Python基础知识(第九天)
125.異常的本質(zhì)_調(diào)試核心理念
異常指程序運(yùn)行過(guò)程中出現(xiàn)的非正常現(xiàn)象,例如用戶輸入錯(cuò)誤、除數(shù)為零、需要處理的文件不存在、數(shù)組下標(biāo)越界等。
所謂異常處理,就是指程序在出現(xiàn)問(wèn)題時(shí)依然可以正確的執(zhí)行剩余的程序,而不會(huì)因?yàn)楫惓6K止程序執(zhí)行。
python 中,引進(jìn)了很多用來(lái)描述和處理異常的類,稱為異常類。異常類定義中包含了該類異常的信息和對(duì)異常進(jìn)行處理的方法。下面較為完整的展示了python 中內(nèi)建異常類的繼承層次:
python 中一切都是對(duì)象,異常也采用對(duì)象的方式來(lái)處理。處理過(guò)程:
1.拋出異常:在執(zhí)行一個(gè)方法時(shí),如果發(fā)生異常,則這個(gè)方法生成代表該異常的一個(gè)對(duì)象,停止當(dāng)前執(zhí)行路徑,并把異常對(duì)象提交給解釋器。
2.捕獲異常:解釋器得到該異常后,尋找相應(yīng)的代碼來(lái)處理該異常。
126.try_一個(gè)except基本結(jié)構(gòu)
try:
? ? 被監(jiān)控的可能引發(fā)異常的語(yǔ)句塊
except BaseException?[as e]:
? ? 異常處理語(yǔ)句塊
try 塊包含著可能引發(fā)異常的代碼,except 塊則用來(lái)捕捉和處理發(fā)生的異常。執(zhí)行的時(shí)候,如果 try 塊中沒(méi)有引發(fā)異常,則跳過(guò) except 塊繼續(xù)執(zhí)行后續(xù)代碼;執(zhí)行的時(shí)候,如果 try塊中發(fā)生了異常,則跳過(guò) try 塊中的后續(xù)代碼,跳到相應(yīng)的 except 塊中處理異常;異常處理完后,繼續(xù)執(zhí)行后續(xù)代碼。
try:print("step1") a = 3/0 print("step2") except BaseException as e: print("step3") print(e)print("step4") step1 step3 division by zero step4127.try_多個(gè)except結(jié)構(gòu)
上面的結(jié)構(gòu)可以捕獲所有的異常,工作中也很常見(jiàn)。但是,從經(jīng)典理論考慮,一般建議盡量捕獲可能出現(xiàn)的多個(gè)異常(按照先子類后父類的順序),并且針對(duì)性的寫(xiě)出異常處理代碼。為了避免遺漏可能出現(xiàn)的異常,可以在最后增加 BaseException。結(jié)構(gòu)如下:
try:被監(jiān)控的、可能引發(fā)異常的語(yǔ)句塊except Exception1:處理 Exception1 的語(yǔ)句塊except Exception2:處理 Exception2 的語(yǔ)句塊...except BaseException:處理可能遺漏的異常的語(yǔ)句塊 try:a = input("請(qǐng)輸入被除數(shù):")b = input("請(qǐng)輸入除數(shù):")c = float(a)/float(b)print(c)except ZeroDivisionError:print("異常:除數(shù)不能為 0") except TypeError:print("異常:除數(shù)和被除數(shù)都應(yīng)該為數(shù)值類型") except NameError:print("異常:變量不存在") except BaseException as e:print(e)print(type(e))128.try...except...else結(jié)構(gòu)
try...except...else 結(jié)構(gòu)增加了“else 塊”。如果 try 塊中沒(méi)有拋出異常,則執(zhí)行 else 塊。如果try 塊中拋出異常,則執(zhí)行 except 塊,不執(zhí)行 else 塊。
try:a = input("請(qǐng)輸入被除數(shù):")b = input("請(qǐng)輸入除數(shù):")c = float(a)/float(b) except BaseException as e:print(e) else:print("除的結(jié)果是:",c)129.try...except...finally結(jié)構(gòu)
try...except...finally 結(jié)構(gòu)中,finally 塊無(wú)論是否發(fā)生異常都會(huì)被執(zhí)行;通常用來(lái)釋放 try 塊中申請(qǐng)的資源。
try:a = input("請(qǐng)輸入一個(gè)被除數(shù):")b = input("請(qǐng)輸入一個(gè)除數(shù):")c = float(a)/float(b) except BaseException as e:print(e) else:print(c) finally:print("我是 finally 中的語(yǔ)句,無(wú)論發(fā)生異常與否,都執(zhí)行!")print("程序結(jié)束!") try:f = open("d:/a.txt",'r')content = f.readline()print(content) except BaseException as e:print(e) finally:print("關(guān)閉資源")try:f.close()except BaseException as e:print(e) print("程序關(guān)閉")130.常見(jiàn)異常匯總和說(shuō)明
return 語(yǔ)句和異常處理問(wèn)題
由于 return 有兩種作用:結(jié)束方法運(yùn)行、返回值。我們一般不把 return 放到異常處理結(jié)構(gòu)中,而是放到方法最后。
常見(jiàn)異常的解決
?
| 異常名稱 | 說(shuō)明 |
| ArithmeticError | 所有數(shù)值計(jì)算錯(cuò)誤的基類 |
| AssertionError | 斷言語(yǔ)句失敗 |
| AttributeError | 對(duì)象沒(méi)有這個(gè)屬性 |
| BaseException | 所有異常的基類 |
| DeprecationWarning | 關(guān)于被棄用的特征的警告 |
| EnvironmentError | 操作系統(tǒng)錯(cuò)誤的基類 |
| EOFError | 沒(méi)有內(nèi)建輸入,到達(dá)EOF 標(biāo)記 |
| Exception | 常規(guī)錯(cuò)誤的基類 |
| FloatingPointError | 浮點(diǎn)計(jì)算錯(cuò)誤 |
| FutureWarning | 關(guān)于構(gòu)造將來(lái)語(yǔ)義會(huì)有改變的警告 |
| GeneratorExit | 生成器(generator)發(fā)生異常來(lái)通知退出 |
| ImportError | 導(dǎo)入模塊/對(duì)象失敗 |
| IndentationError | 縮進(jìn)錯(cuò)誤 |
| IndexError | 序列中沒(méi)有此索引(index) |
| IOError | 輸入/輸出操作失敗 |
131.with上下文管理
finally 塊由于是否發(fā)生異常都會(huì)執(zhí)行,通常我們放釋放資源的代碼。其實(shí),我們可以通過(guò) with 上下文管理,更方便的實(shí)現(xiàn)釋放資源的操作。
with 上下文管理的語(yǔ)法結(jié)構(gòu)如下:with context_expr?[ as var]: 語(yǔ)句塊
with 上下文管理可以自動(dòng)管理資源,在 with 代碼塊執(zhí)行完畢后自動(dòng)還原進(jìn)入該代碼之前的現(xiàn)場(chǎng)或上下文。不論何種原因跳出 with 塊,不論是否有異常,總能保證資源正常釋放。極大的簡(jiǎn)化了工作,在文件操作、網(wǎng)絡(luò)通信相關(guān)的場(chǎng)合非常常用。
with open("d:/bb.txt") as f: for line in f:print(line)132.trackback模塊的使用_異常寫(xiě)入日志文件
trackback模塊的使用
import traceback try:print("step1")num = 1/0 except:traceback.print_exc() Traceback (most recent call last):File "/Users/zhucan/PycharmProjects/pythonProject1/mypy01.py", line 4, in <module>num = 1/0 ZeroDivisionError: division by zero step1異常寫(xiě)入日志文件
? import traceback try:print("step1")num = 1/0 except:with open("d:/a.log","a") as f:traceback.print_exc(file=f)?133.自定義異常類_raise拋出異常
自定義異常類
程序開(kāi)發(fā)中,有時(shí)候我們也需要自己定義異常類。自定義異常類一般都是運(yùn)行時(shí)異常,通常繼承 Exception 或其子類即可。命名一般以 Error、Exception 為后綴。
class AgeError(Exception):def __init__(self,errorInfo):Exception. __init__(self)self.errorInfo = errorInfodef __str__(self):return str(self.errorInfo)+",年齡錯(cuò)誤!應(yīng)該在 1-150 之間"if __name__ == "__main__":age = int(input("輸入一個(gè)年齡:"))if age<1 or age>150:raise AgeError(age)else:print("正常的年齡:",age)134.pycharm的調(diào)試模式
進(jìn)行調(diào)試的核心是設(shè)置斷點(diǎn)。程序執(zhí)行到斷點(diǎn)時(shí),暫時(shí)掛起,停止執(zhí)行。就像看視頻按下停止一樣,我們可以詳細(xì)的觀看停止處的每一個(gè)細(xì)節(jié)。
斷點(diǎn)
程序運(yùn)行到此處,暫時(shí)掛起,停止執(zhí)行。我們可以詳細(xì)在此時(shí)觀察程序的運(yùn)行情況,方便做出進(jìn)一步的判斷。
1.設(shè)置斷點(diǎn)
(1)在行號(hào)后面單擊即可增加斷點(diǎn)
?
(2)在行號(hào)后面單擊即可增加斷點(diǎn)
進(jìn)入調(diào)試視圖
我們通過(guò)如下三種方式都可以進(jìn)入調(diào)試視圖:
1.單擊工具欄上的按鈕:
2.右鍵單擊編輯區(qū),點(diǎn)擊:debug?‘模塊名’
3.快捷鍵:shift+F9
?進(jìn)入調(diào)試視圖后,布局如下:
?
左側(cè)為“瀏覽幀”:調(diào)試器列出斷點(diǎn)處,當(dāng)前線程正在運(yùn)行的方法,每個(gè)方法對(duì)應(yīng)一個(gè)“棧幀”。最上面的 ?是當(dāng)前斷點(diǎn)所處的方法。
變量值觀察區(qū):調(diào)試器列出了斷點(diǎn)處所在方法相關(guān)的變量值。我們可以通過(guò)它,查看變量的值的變化,也可以通過(guò)?,增加要觀察的變量。
我們通過(guò)上圖中的按鈕進(jìn)行調(diào)試操作,它們的含義如下:
| 中文名稱 | 英文名稱 | 圖標(biāo)和快捷鍵 | 說(shuō)明 |
| 顯示當(dāng)前所有斷點(diǎn) | show Execution Point | Alt+F10 | |
| 單步調(diào)試: 遇到函數(shù)跳過(guò) | step over | F8 | 若當(dāng)前執(zhí)行的是一個(gè)函數(shù),則會(huì)把這個(gè) 函數(shù)當(dāng)做整體一步執(zhí)行完。不會(huì)進(jìn)入這個(gè)函數(shù)內(nèi)部 |
| 單步調(diào)試: 遇到函數(shù)進(jìn)入 | step into | F7? | 若當(dāng)前執(zhí)行的是一個(gè)函數(shù),則會(huì)進(jìn)入這個(gè)函數(shù)內(nèi)部 |
| 跳出函數(shù) | step out | Shift+F8 | 當(dāng)單步執(zhí)行到子函數(shù)內(nèi)時(shí),用 step out 就可以執(zhí)行完子函數(shù)余下部分,并返回到上一層函數(shù) |
| 執(zhí)行的光標(biāo)處 | run to cursor | Alt+F9 | 一直執(zhí)行,到光標(biāo)處停止,用在循環(huán)內(nèi) 部時(shí),點(diǎn)擊一次就執(zhí)行一個(gè)循環(huán) |
總結(jié)
以上是生活随笔為你收集整理的Python基础知识(第九天)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Python基础知识(第八天)
- 下一篇: Python基础知识(第十天)