Tacacs-雙通道認證配置測試與總結
阿新 • • 發佈:2020-12-28
title: python異常處理
data: 2018-4-6
categories:
- python
tags: - python
try...except
有時候寫程式的時候,會出現一些錯誤或異常,導致程式終止。例如,做除法時,除數為0,會引起一個ZeroDivisionError
a=10
b=0
c=a/b
print("done")
執行結果:
Traceback (most recent call last):
...
ZeroDivisionError: division by zero
發現程式因為 ZeroDivisionError 而中斷了,語句 print("done") 沒有執行。為了處理異常,使用 try...except,更改程式碼:
a=10
b=0
try:
c=a/b
print(c)
except (ZeroDivisionError, TypeError) as e:
print(e)
print("done")
執行結果:
division by zero
done
這樣程式就不會因為異常而中斷,從而 print("done") 語句正常執行。
把可能發生錯誤的語句放在 try 模組裡,用 except 來處理異常。except 可以處理一個專門的異常,也可以處理一組圓括號中的異常,如果 except 後沒有指定異常,則預設處理所有的異常。每一個 try,都必須至少有一個 except
處理一組異常可以這樣寫(其中e代表異常的例項):
try:
pass
except (IOError, ZeroDivisionError) as e:
print(e)
Python 常見的標準異常類
異常名稱 | 描述 |
---|---|
Exception | 所有異常的基類 |
AttributeError | 特徵引用或者賦值失敗時引發的 |
IOError | 試圖打在不存在的檔案(包括其他情況) |
IndexError | 使用序列中不存在的索引 |
KeyError | 使用對映中不存在的鍵 |
NameError | 找不到名字(變數) |
SyntaxError | 在程式碼為錯誤形式時引發 |
SystemExit | 系統異常退出 |
TypeError | 在內建操作或者函式應用與錯誤型別的物件時 |
ValueError | 正確的型別物件,但是物件使用不合適的值 |
ZeroDivisionError | 除法,第二引數為0 |
捕捉異常
基本形式:
try:
需要執行的操作
except 異常類 as e:
如果發生異常,執行以下程式碼
else:
如果沒有發生異常,執行的命令
finally:
無論如何,都要執行的程式碼
- 注意 except as e 的寫法,e 是一個變數,記錄了異常的類,可以用 print 函式打印出來
- except 後面的異常類,建議寫 Exception,這樣就一定能捕獲到異常。
捕獲到異常,就不會去執行 else 模組
示例:
try:
name = input('Please input your name: ')
print('Hello %s' %name)
print(10/0)
except Exception as e:
print('Got an error ', e)
else:
print('OK')
finally:
print('Game over')
Please input your name: zhong
Hello zhong
Got an error division by zero
Game over
再舉個例子:
import urllib.request
def main():
try:
response = urllib.request.urlopen("http://210.35.16.108")
# response = urllib.request.urlopen("https://www.baidu.com")
except Exception as e:
# raise
print(e)
else:
print('無異常則執行,有異常就不執行')
finally:
print('不管怎樣,最後總會執行這行程式碼')
if __name__ == '__main__':
main()
結果:
<urlopen error [WinError 10060] 由於連線方在一段時間後沒有正確答覆或連線的主機沒有反應,連線嘗試失敗。>
不管怎樣,最後總會執行這行程式碼
[Finished in 21.5s]
捕獲多個異常
方法一:
try:
需要執行的操作
except 異常類1 as e:
如果發生異常類1,執行以下程式碼
except 異常類2 as f:
如果發生異常類2,執行以下程式碼
else:
如果沒有發生異常,執行的命令
finally:
無論如何,都要執行的程式碼
- except 後面的異常類,如果無需指定,直接寫 Exception 即可。
- 如果需要明確指定異常的類,而且是多個類的情況下,可以使用多個 except 語句。
方法二:
try:
需要執行的操作
except (異常類1,異常2,異常3) as e:
如果發生異常,執行以下程式碼
else:
如果沒有發生異常,執行的命令
finally:
無論如何,都要執行的程式碼
丟擲異常
raise 關鍵字可以自主丟擲異常,規則如下:
raise NameError([str])
- raise 後面跟異常的類,類括號裡面,可以指定要丟擲的異常示例,約詳細越好
>>> raise NameError()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError
>>> raise NameError('bad name')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: bad name
例如:
# 當你輸入的不是整數,它會報錯(ValueError),但你輸入的是一個整數後,它會輸出你輸入的整數。
Q = input("請輸入一個整數:")
if type(Q) != type(1):
raise ValueError
else:
print(Q)
Q = input("請輸入一個整數:")
if type(Q) != type(1):
raise leixingError("型別錯誤!")
else:
print(Q)
總結如下
except
語句不是必須的,finally
語句也不是必須的,但是二者必須要有一個,否則就沒有try
的意義了。except
語句可以有多個,Python會按except
語句的順序依次匹配你指定的異常,如果異常已經處理就不會再進入後面的except
語句。except
語句可以以元組形式同時指定多個異常,參見例項程式碼。except
語句後面如果不指定異常型別,則預設捕獲所有異常,你可以通過logging或者sys模組獲取當前異常。- 如果要捕獲異常後要重複丟擲,請使用
raise
,後面不要帶任何引數或資訊。 - 不建議捕獲並丟擲同一個異常,請考慮重構你的程式碼。
- 不建議在不清楚邏輯的情況下捕獲所有異常,有可能你隱藏了很嚴重的問題。
- 儘量使用內建的異常處理語句來替換
try/except
語句,比如with
語句,getattr()
方法。