本次講解的是Python中最常見的異常處理,這種異常是什麼?異常和錯誤相同嗎?要如何處理這種異常?看完這篇文章你或許會有所收獲
推薦一個我正在用的好用刷題網站由此進入免費的刷題練習網站
文章目錄
一、異常和錯誤初識
1、錯誤
1.1、語法錯誤
1.2、邏輯錯誤
2、異常
1.1異常類型
3、異常和錯誤的關聯
二、異常處理的概念
1、什麼是異常處理
2、異常處理有什麼好處
三、異常處理操作
1、初階語法格式
1.1、注意
2、萬能異常
3、高階語法格式
3.1、注意
3.2、顯示異常的原因
四、總結異常處理
錯誤分為兩大類:一類是語法錯誤、另一類是邏輯錯誤,錯誤是非正常的,不應該出現的,比如:縮進,定義函數時未加冒號等等
這種錯誤是最不應該出現的,根本過不了python解釋器的語法檢測,必須在程序執行前就改正
比如以下這幾種一眼就發現的語法錯誤就要盡量避免:
錯誤示例一 if a 錯誤示例二 def func:
不完整或不合法輸入、算法問題,比如0作除數
比如你要求用戶輸入一個數字,但是用戶偏要輸入字母這就可能導致你後面的代碼發生錯誤這就算一種邏輯錯誤
a = input('請輸入一個數字:') b = int(a) 用戶輸入: abcdefg 程序輸出: ValueError: invalid literal for int() with base 10: 'abcdefg'
程序遇到邏輯或者算法問題運行過程中計算機錯誤(內存不夠或IO錯誤)這兩個或拋出異常,如果沒有手動對其進行處理,那麼此異常就會被解釋器捕獲,處理的方法為忽略或者終止程序
比如:
- 全部異常類型:
ArithmeticError
AssertionError
AttributeError
BaseException
BufferError
BytesWarning
DeprecationWarning
EnvironmentError
EOFError
Exception
FloatingPointError
FutureWarning
GeneratorExit
ImportError
ImportWarning
IndentationError
IndexError
IOError
KeyboardInterrupt
KeyError
LookupError
MemoryError
NameError
NotImplementedError
OSError
OverflowError
PendingDeprecationWarning
ReferenceError
RuntimeError
RuntimeWarning
StandardError
StopIteration
SyntaxError
SyntaxWarning
SystemError
SystemExit
TabError
TypeError
UnboundLocalError
UnicodeDecodeError
UnicodeEncodeError
UnicodeError
UnicodeTranslateError
UnicodeWarning
UserWarning
ValueError
Warning
ZeroDivisionError
- 部分異常類型解釋:
ZeroDivisionError
除法運算中除數0 或者 取模運算中模數為0
AttributeError
試圖訪問一個對象沒有的樹形,比如foo.x,但是foo沒有屬性x
IOError輸入/輸出異常;基本上是無法打開文件
ImportError無法引入模塊或包;基本上是路徑問題或名稱錯誤
IndentationError語法錯誤(的子類) ;代碼沒有正確對齊
IndexError下標索引超出序列邊界,比如當x只有三個元素,卻試圖訪問x[5]
KeyError試圖訪問字典裡不存在的鍵
KeyboardInterruptCtrl+C被按下
NameError使用一個還未被賦予對象的變量
SyntaxErrorPython代碼非法,代碼不能編譯(個人認為這是語法錯誤,寫錯了)
TypeError傳入對象類型與要求的不符合
UnboundLocalError試圖訪問一個還未被設置的局部變量,基本上是由於另有一個同名的全局變量,導致你以為正在訪問它
ValueError傳入一個調用者不期望的值,即使值的類型是正確的
錯誤是代碼運行前錯誤是非正常的,不應該出現的,比如:縮進、循環語句的冒號
異常是由錯誤產生的異常是代碼運行時產生的 ,解釋器檢測到錯誤你並且認為是異常,拋出異常如果不捕獲處理可能會終止程序我們可以在代碼中主動捕獲異常並處理
python解釋器檢測到錯誤,觸發異常(也允許程序員自己觸發異常)
程序員編寫特定的代碼,專門用來捕捉這個異常(這段代碼與程序邏輯無關,與異常處理有關)
如果捕捉成功則進入另外一個處理分支,執行你為其定制的邏輯,使程序不會崩潰,這就是異常處理
python解析器去執行程序,檢測到了一個錯誤時,觸發異常,異常觸發後且沒被處理的情況下,程序就在當前異常處終止,後面的代碼不會運行,這可能會導致你的軟件崩潰,誰會去使用一個突然就閃退的軟件呢?
所以你必須提供一種異常處理機制來增強你程序的健壯性與容錯性 ,至少程序不會崩潰。
python為每一種異常定制了一個類型,然後提供了一種特定的語法結構try和except用來進行異常處理
語法如下:
try: 我們需要處理的代碼 except 後面跟一個錯誤類型: 當try中的代碼發生錯誤且錯誤的類型符合時, 就會執行except下面的代碼 except 後面跟一個錯誤類型: 當try中的代碼發生錯誤且錯誤的類型符合時, 就會執行except下面的代碼 …… 支持多分支
單分支
try: print('檢測出異常前是否會執行') ret = int(input('請輸入>>>')) print(ret*'*') print('檢測出異常後是否會執行') except ValueError: print('你的輸入有誤')
輸出結果
多分支
try: [1,2][4] ret = int(input('請輸入>>>')) print(ret*'*') #[][4] except ValueError: print('你的輸入有誤,請輸入一個數字') except IndexError: print('超出了列表的最大長度')
輸出結果
從上面我們知道當try下面的代碼有多個錯誤,且錯誤都符合 except分支的錯誤類型,則代碼會在第一個符合的錯誤類型後停止,並且輸出相對應的except分支下的代碼。
有沒有一種可能try後面的代碼是沒有錯誤的,所以不符合任何錯誤類型,那麼執行上面的語法格式後就會報錯
try: a = 1 print(a) except Exception: print('沒有錯誤')
輸出結果
解決方法:
try: a = 1 print(a) except Exception: print('沒有錯誤') else: print('代碼沒有異常') 輸出結果: 代碼沒有異常
在python的異常中,有一個萬能異常:Exception,他可以捕獲任意異常
try: print('111111') 1/0 print('222222') name = a b = 2 + '3' {}['k'] except Exception: print('你錯了老鐵')
輸出結果
注意: 有了萬能處理機制仍然需要把能預測到的問題單獨處理
單獨處理的所有內容都應該寫在萬能異常之前
try: 我們需要處理的代碼 except 後面跟一個錯誤類型: 當try中的代碼發生錯誤且錯誤的類型符合時, 就會執行except下面的代碼 else: 需要處理的代碼一段正常代碼時執行 finally: 不管需要處理的代碼異不異常,都會執行
栗子:
def func(): try: print('這是一段正常代碼') return True except: return False else: print('這是一段正常代碼') finally: print('執行finally了')
輸出結果:
雖然上面需要處理的代碼一段正常代碼,但是由於有return,else裡的代碼也不會執行
但是 finally不管代碼是否異常,都會執行,finally和return相遇的時候,依然會執行
所以finally一般在函數中做異常處理
用以下代碼會輸出你代碼第一處錯誤的原因
try: a = b 1/0 [1,2,4][100] except Exception as e: print(e) 輸出結果: name 'b' is not defined
try..except這種異常處理機制就是取代if那種方式,讓你的程序在不犧牲可讀性的前提下增強健壯性和容錯性異常處理中為每一個異常定制了異常類型(python中統一了類與類型,類型即類),對於同一種異常,一個except就可以捕捉到,可以同時處理多段代碼的異常(無需‘寫多個if判斷式’)減少了代碼,增強了可讀性
使用try..except的方式
- 把錯誤處理和真正的工作分開來
- 代碼更易組織,更清晰,復雜的工作任務更容易實現;
- 毫無疑問,更安全了,不至於由於一些小的疏忽而使程序意外崩潰了;
學完了異常處理後,就又人會想好強大,我要為我的每一段程序都加上try...except,這樣代碼就不會報錯了,多好!!等等先打住!!因為你寫的這段代碼,可能根本完成不了你的需求,你甚至都不知道要改哪裡才能夠實現。
try...except應該盡量少用,因為它本身就是你附加給你的程序的一種異常處理的邏輯,與你的主要的工作是沒有關系的這種東西加的多了,會導致你的代碼可讀性變差,只有在有些異常無法預知的情況下,才應該加上try...except,其他的邏輯錯誤應該盡量修正
:別忘了刷題喲由此進入免費好用的刷題網站
:感謝各位能夠看到這裡:在魯迅一篇未發表的文章中說過:“代碼看懂了不是懂一定要自己實際操作哇這樣才能更好的理解和吸收。”
最後來一句:一個人可以在任何他懷有無限熱忱的事情上成功,讓我們一起進步吧