進擊のpython
異常捕獲
什么叫做異常捕獲???我們分開來理解
什么是異常??什么又叫捕獲呢?
異常?那不是你經常做出來的嘛
不信??
你看看這些,你熟悉不??
NameError: name 'w' is not defined
ValueError: invalid literal for int() with base 10: 'w'
TypeError: 'int' object is not iterable
SyntaxError: Non-UTF-8 code starting with '\xce' in file
...
是不是都是你曾經的傑作呢???
吶,又要開始學新的英語單詞了
Error : 錯誤,異常
那么NameError就是變量異常
同理TypeError就是類型異常
看!一場是不是就出來了!
異常其實說白了不就是
你平時寫代碼出來的各種報錯嗎!
哈哈哈,扎鐵了老心!
那既然我們已經知道了什么是異常了
那捕獲呢?捕捉是個動詞是吧
(哥哥,你別告訴我你不知道這是動詞)
那我們為什么要捕獲異常呢?
一個最簡單的例子,我要輸入兩個數字,然后求和
因為用戶的輸入都是字符串類型是吧
(不知道???那我就想錘你了)
所以我們是不是還需要把字符串類型的數字變成整型
是不是就要用int()給他處理一下!
對吧!邏輯沒問題吧
但是你又發現了,我要是輸入的不是數字,就會給我報錯
然后程序就終止了!
但是我想做的是報錯了,我就跟他說你錯了,然后程序重新運行
這要求不過分吧!那么就要用到異常捕獲了!
如果你有異常,我就給你抓起來,不讓你報錯,那你程序不就能執行了嘛
如果我再想提示你個什么信息我就寫出來就完事了唄
那理論有了,我們來看看這玩仍到底怎么寫
兩個關鍵字 try except
while 1:
try:
m = int(input("請輸入第一個加數:"))
n = int(input("請輸入第二個加數:"))
print(m + n)
except:
print("請輸入數字")
用上面兩個關鍵字把你要捕捉異常的代碼放進去("就是你覺得可能會報錯的代碼塊!")
這個寫法格式就有點像 if-elif 的格式寫法
好了!基本的格式和寫法就是這樣的
但是啊,以你現在的技術,你就會報一個錯誤??
想什么呢湊弟弟!
還不是改一個又出來一個錯誤!
那這么多錯誤,我想針對不同的錯誤,有不同的提示
要怎么寫呢?????
這就用到了咱們最先的學到的那幾個英語單詞了
簡單來說就是用 不同的網抓不同的魚
我們有多少張網呢?
給你點常用的先感受一下
AttributeError 試圖訪問一個對象沒有的屬性,比如foo.x,但是foo沒有屬性x
IOError 輸入/輸出異常;基本上是無法打開文件
ImportError 無法引入模塊或包;基本上是路徑問題或名稱錯誤
IndentationError 語法錯誤(的子類) ;代碼沒有正確對齊
IndexError 下標索引超出序列邊界,比如當x只有三個元素,卻試圖訪問x[5]
KeyError 試圖訪問字典里不存在的鍵
KeyboardInterrupt Ctrl+C被按下
NameError 使用一個還未被賦予對象的變量
SyntaxError Python代碼非法,代碼不能編譯(個人認為這是語法錯誤,寫錯了)
TypeError 傳入對象類型與要求的不符合
UnboundLocalError 試圖訪問一個還未被設置的局部變量,基本上是由於另有一個同名的全局變量,導致你以為正在訪問它
ValueError 傳入一個調用者不期望的值,即使值的類型是正確的
再給你點不常用的,你看看就好
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
我們有這么多張網,怎么用呢?
上面的程序,如果我輸入的是非數字是不是報的是ValueError
(你要不知道,你就把 try-except 去掉,然后輸入非數字,你看看提示的是什么)
(別的找錯方式也可以這樣!)
那我們就可以這么寫
while 1:
try:
m = int(input("請輸入第一個加數:"))
n = int(input("請輸入第二個加數:"))
print(m + n)
except ValueError:
print("請輸入數字")
為什么說是和 if-elif 相似的格式呢?
if-elif 是不是多選一啊
我們也可以!
while 1:
try:
k
m = int(input("請輸入第一個加數:"))
n = int(input("請輸入第二個加數:"))
print(m + n)
except ValueError:
print("請輸入數字")
看,我是不是定義個變量,但是沒有賦值,那就回報這個錯誤:NameError: name 'k' is not defined
我們要是想抓這條魚,怎么做呢?多選一嘛!
while 1:
try:
k
m = int(input("請輸入第一個加數:"))
n = int(input("請輸入第二個加數:"))
print(m + n)
except ValueError:
print("請輸入數字")
except NameError:
print("含有未定義的變量")
對吧!是不是寫法挺像 if-elif 的
如果你想兩個不同的錯誤都提示相同的信息
你也可以進行合寫!
except (ValueError,NameError)
那,是什么錯誤,都能捕獲嗎?????
a = 100
if a == 100:
print("hahah")
會報錯,報了一個什么錯呢? IndentationError: expected an indented block
那我們就用 try-except 來捕捉這個錯誤
練習自己捕捉!
你會發現這個錯誤你是捕捉不了的
其實不光是這個錯誤,還有些別的錯誤你也是捕捉不到的
什么語法錯誤 SyntaxError: invalid syntax 啊之類的
就等你自己發現啦!
那,很明顯
我要是錯誤很多,然后除了幾個錯誤之外,別的我都不想寫了
那我可以推薦你個好方法!萬能異常!
簡單來說就是一堵牆,它可以攔住漏過你前面網的所有魚
那既然我都這么說了
很明顯,這堵牆的位置應該在所有網的最后面
這堵牆長什么樣呢?
except Exception:
那除了那么寫的,還有別的
你想啊 if-elif 是不是后面還可以延伸一個else?
那try-except 也可以延伸出一個else
if-elif-else else是不是放在最后?
那 try-except-else 中的else也應該放在最后
if-elif-else 中的else是不是所有的都沒執行才執行else?
那try-except-else 中的else就應該是所有錯誤都沒出才執行!
對吧!類比學習嘛!
那除了除了以上的格式,其實還有別的
try-except-else-finally 多了個finally
那finally的作用其實就是你錯沒錯都是會執行的
(代碼自己敲!很簡單的)
那我們為了工作需要,有的時候也會主動拋出異常
那主動拋出異常就有要學一個詞了:raise
他就會拋出一個指定的異常,比如 raise NameError
就是我主動拋出一個叫做 NameError 的異常
那我主動拋出異常有什么用呢??
比如在以后的某天,你厲害了,自己寫了個軟件
那對於應用級的異常,就只能自己拋出特殊的異常
(而這個異常,往往是自己定義的,下面會提)
那這個時候就需要raise
我們可以學一下如何自定義一個異常
其實你定義的所有異常,都是繼承一個叫BaseException類
我們可以把錯誤信息放在構造函數里面
def __init__(self, msg):
self.msg = msg
然后我們還要再寫一個這個
def __Str__(self):
return self.msg
最后我們進行拼裝一下,並進行測試
class MyError(BaseException):
def __init__(self, msg):
self.msg = msg
def __Str__(self):
return self.msg
try:
raise MyError("我錯了!")
except MyError as e:
print(e)
自己看結果
同時啊,這里還要強調一點
就是這種自己搞得異常,萬能異常都是捕捉不到的!