下面是小凰凰的簡介,看下吧!
💗人生態度:珍惜時間,渴望學習,熱愛音樂,把握命運,享受生活
💗學習技能:網絡 -> 雲計算運維 -> python全棧( 當前正在學習中)
💗您的點贊、收藏、關注是對博主創作的最大鼓勵,在此謝過!
有相關技能問題可以寫在下方評論區,我們一起學習,一起進步。
後期會不斷更新python全棧學習筆記,秉着質量博文爲原則,寫好每一篇博文。
文章目錄
注意:光理論是不夠的,在此送大家一套2020最新Python全棧實戰視頻教程,點擊此處 免費獲取一起進步哦!
一、什麼是異常
異常是程序發生錯誤的信號。程序一旦出現錯誤,便會產生一個異常,若程序中沒有處理它,就會拋出該異常,程序的運行也隨之終止。在Python中,錯誤觸發的異常如下:
而錯誤分成兩種,一種是語法上的錯誤SyntaxError,這種錯誤應該在程序運行前就修改正確,
另一類就是邏輯錯誤,常見的邏輯錯誤如:
# TypeError:數字類型無法與字符串類型相加
1+’2’
# ValueError:當字符串包含有非數字的值時,無法轉成int類型
num=input(">>: ") #輸入hello
int(num)
# NameError:引用了一個不存在的名字x
x
# IndexError:索引超出列表的限制
l=['egon','aa']
l[3]
# KeyError:引用了一個不存在的key
dic={'name':'egon'}
dic['age']
# AttributeError:引用的屬性不存在
class Foo:
pass
Foo.x
# ZeroDivisionError:除數不能爲0
1/0
二、異常處理
1、異常處理完全形式(總結性)
爲了保證程序的容錯性與可靠性,即在遇到錯誤時有相應的處理機制不會任由程序崩潰掉,我們需要對異常進行處理,處理的完全形式爲:
try:
被檢測的代碼塊
except (異常類型1,異常類型2) as e:# 一般用於幾種類型異常處理方式完全相同的情況,比如處理方式都是把異常值e寫入日誌文件。
檢測到這兩種其中一種類型異常,就執行這個位置的邏輯
except 異常類型:
檢測到類型異常,就執行這個位置的邏輯
else:
沒檢測任何異常,就執行這個位置的邏輯
finally:
無論是否有異常,這裏的代碼都會被執行。一般此處放回收系統資源的代碼,避免出現異常結束程序了,系統資源還沒有回收的情況。
2、處理的子形式之try+accept
try:
print('start...')
print(x) # 引用了一個不存在的名字,觸發異常NameError
print('end...')
except NameError as e: # as語法將異常類型的值賦值給變量e,這樣我們通過打印e便可以知道錯誤的原因,一般產生的異常都需要寫進錯誤日誌中去。
print('異常值爲:%s' %e)
print('run other code...')
#執行結果爲
start...
異常值爲:name 'x' is not defined
run other code...
如果我們想多種類型的異常統一用一種邏輯處理,可以將多個異常放到一個元組內,用一個except匹配
try:
被檢測的代碼塊
except (NameError,IndexError,TypeError):
觸發NameError或IndexError或TypeError時對應的處理邏輯
舉例:
def convert_int(obj):
try:
res=int(obj)
except (ValueError,TypeError):
print('argument must be number or numeric string')
res=None
return res
convert_int('egon') # argument must be number or numeric string
convert_int({'n':1}) # argument must be number or numeric string
如果我們想捕獲所有異常並用一種邏輯處理
,Python提供了一個萬能異常類型Exception:
try:
被檢測的代碼塊
except NameError:
觸發NameError時對應的處理邏輯
except IndexError:
觸發IndexError時對應的處理邏輯
except Exception:
其他類型的異常統一用此處的邏輯處理
3、處理的子形式之try+accept+else
在多分支except之後還可以跟一個else(else必須跟在except之後,不能單獨存在),只有在被檢測的代碼塊沒有觸發任何異常的情況下才會執行else的子代碼塊
try:
被檢測的代碼塊
except 異常類型1:
pass
except 異常類型2:
pass
......
else:
沒有異常發生時執行的代碼塊
4、處理的子形式之try+finally、try+except+finally
此外try還可以與finally連用,從語法上講finally必須放到else之後,但可以使用try-except-finally的形式,也可以直接使用try-finally的形式
。無論被檢測的代碼塊是否觸發異常,都會執行finally的子代碼塊,因此通常在finally的子代碼塊做一些回收資源的操作,比如關閉打開的文件、關閉數據庫連接等
f=None
try:
f=open(‘db.txt’,'r',encoding='utf-8')
s=f.read().strip()
int(s) # 若字符串s中包含非數字時則會觸發異常ValueError
# f.close() # 若上面的代碼觸發異常,則根本不可能執行到此處的代碼,應該將關閉文件的操作放到finally中
finally:
if f: # 文件存在則f的值不爲None
f.close()
5、主動觸發異常(raise語句)
在不符合Python解釋器的語法或邏輯規則時,是由Python解釋器主動觸發的各種類型的異常,而對於違反程序員自定製的各類規則,則需要由程序員自己來明確地觸發異常,這就用到了raise語句,raise後必須是一個異常的類或者是異常的實例
class Student:
def __init__(self,name,age):
if not isinstance(name,str):
raise TypeError('name must be str')
if not isinstance(age,int):
raise TypeError('age must be int')
self.name=name
self.age=age
stu1=Student(4573,18) # TypeError: name must be str
stu2=Student('egon','18') # TypeError: age must be int
6、自定義異常類
我們raise語句後面需要跟一個異常的類或者是異常的實例,因此如果內置異常不能滿足我們的需求,我們可以通過繼承內置的異常類來自定義異常類
:
class PoolEmptyError(Exception): # 可以通過繼承Exception來定義一個全新的異常
def __init__(self,value='The proxy source is exhausted'): # 可以定製初始化方法
super(PoolEmptyError,self).__init__()
self.value=value
def __str__(self): # 可以定義該方法用來定製觸發異常時打印異常值的格式
return '< %s >' %self.value
class NetworkIOError(IOError): # 也可以在特定異常的基礎上擴展一個相關的異常
pass
raise PoolEmptyError # __main__.PoolEmptyError: < The proxy source is exhausted >
raise NetworkIOError('連接被拒絕') # __main__.NetworkIOError: 連接被拒絕
7、斷言(assert語句)
最後,Python還提供了一個斷言語句assert expression,斷定表達式expression成立,否則觸發異常AssertionError,與raise-if-not的語義相同,如下
age='18'
# 若表達式isinstance(age,int)返回值爲False則觸發異常AssertionError
assert isinstance(age,int)
# 等同於
if not isinstance(age,int):
raise AssertionError
三、何時使用異常處理
在瞭解了異常處理機制後,本着提高程序容錯性和可靠性的目的,讀者可能會錯誤地認爲應該儘可能多地爲程序加上try...except...,這其是在過度消費程序的可讀性
,因爲try…except本來就是你附加給程序的一種額外的邏輯,與你的主要工作是沒有多大關係的。
異常分爲兩種可預知和不可預知!只有在不可預知的情況下,才使用異常處理。
1、可預知異常的處理
如果錯誤發生的條件是“可預知的”,我們應該用if來進行”預防”
,如下:
age=input('input your age>>: ').strip()
if age.isdigit(): # 可預知只有滿足字符串age是數字的條件,int(age)纔不會觸發異常,
age=int(age)
else:
print('You must enter the number')
2、不可預知異常的處理
如果錯誤發生的條件“不可預知”
,那麼我們才應該使用try…except語句來處理。例如我們編寫一個下載網頁內容的功能,網絡發生延遲之類的異常是很正常的事,而我們根本無法預知在滿足什麼條件的情況下才會出現延遲,因而只能用異常處理機制了
import requests
from requests.exceptions import ConnectTimeout # 導入requests模塊內自定義的異常
def get(url):
try:
response=requests.get(url,timeout=3)#超過3秒未下載成功則觸發ConnectTimeout異常
res=response.text
except ConnectTimeout:
print('連接請求超時')
res=None
except Exception:
print('網絡出現其他異常')
res=None
return res
get('https://www.python.org')
注意:最後送大家一套2020最新企業Pyhon項目實戰視頻教程,點擊此處 免費獲取一起進步哦!