錯誤
可以通過IDE或者解釋器給出提示的錯誤
opentxt('a.jpg','r')
語法層面沒有問題,但是自己代碼的邏輯有問題
if age>18: print('未成年')
異常
多指在程序執行過程中,出現的未知錯誤,語法和邏輯本身是正確的。可以通過代碼進行處理或修復
異常分類1/0
if age>5,age未定義
1+'abc'
a=[1,2,3] a[4]
a={'a':1,'b':2} a['c']
int('abcd')
name='Dracular' print(name.age)
a=iter([1,2]) print(next(a)) print(next(a)) print(next(a))
異常處理格式# python 的完整異常處理格式,原諒我蹩腳的英語注釋,哈哈...
# python 2 中except exception_type, error
# python 3 中except exception_type as error
try:
do something
except exception_type1:
when get exception_type1 error
except exception_type2:
when get exception_type2 error
except exception_typen:
when get exception_type2 error
else:
if not get error,into here
finally:
always execute it ...
剛才介紹了很多異常的分類,也看到了異常處理的格式,那麼針對多種異常如何更簡潔的捕獲呢?
使用with處理異常用於執行一段代碼前,進行預處理,執行完成這段代碼後,進行清理操作
with content_expression[as target(s)]: withbody
大家用到最多的莫過於在讀寫文件時,使用with open
with open('a.txt','a') as file :
file.write('first line...')
為什麼說他是一個上下文處理器呢?
首先咱們在文件讀寫的時候主要分三個步驟:
打開文件
操作文件的內容
關閉文件
正常情況下,我們使用的方式為:
f=open('a.txt', 'a')
f.write('first line...')
f.close()
那麼如果我們在操作文件的時候,出現了異常導致系統退出,就無法正常的關閉文件
但使用with的上下文管理器,就可以達到異常退出時的清理操作!
可是沒有論證,空口在這裡吹逼不太好啊,舉個例子來驗證with自帶的異常清理。
先看下這段代碼:
import os
try:
f=open('a.txt', 'a+')
f.write('first line...')
raise ValueError
except:
os.rename('a.txt','b.txt')
f.close()
output:
PermissionError: [WinError 32] 另一個程序正在使用此文件,進程無法訪問。: 'a.txt' -> 'b.txt'
我們在寫文件的時候,手動出發一個異常,然後在except捕獲異常後,去重命名該文件。
然後由於沒有正常的關閉,此時你去重命名會給出文件正在佔用的提示
那同樣的方式,我們使用with操作看看效果:
import os
try:
with open('a.txt', 'a+') as file:
file.write('first line...')
raise ValueError
except:
os.rename('a.txt','b.txt')
此時正常執行完成,程序沒有拋出異常,為什麼?因為在上下文處理器中,with捕獲異常後,自動的執行了文件的關閉操作,溜不溜?
上下文管理器原理所謂上下文管理器的原理,其實就是以下三點
調用enter 方法,進行預處理操作
執行用戶操作
調用exit方法,完成清理操作
知道了原理,讓我們通過自己編寫的上下文管理器,重構一下open的方法,讓它裝逼即耀眼又安全吧
import os
# 自定義一個上下文管理器
class zhuang13_open:
def __init__(self, file, mode):
self.file = file
self.mode = mode
def __enter__(self):
print('啟動裝13模式,打開文件-->%s' % self.file)
self.file = open(self.file, mode=self.mode)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
print('亂花從中過,片葉不沾身\n裝完13,記得擦屁股啊')
self.file.close()
# 依舊測試下在異常的情況下是否可以正常關閉文件
try:
with zhuang13_open('a.txt', 'a+') as file:
file.write('first line...')
raise ValueError
except:
os.rename('a.txt', 'b.txt')
完美結束....
了解下剛才的__exit__剛才看到在定義__exit__方法時,自帶了三個參數exc_type, exc_val, exc_tb
這是什麼呢?分別為:異常類別,異常值,追蹤信息,怎麼看他的值呢?
把上面代碼中raise ValueError改為1/0
在__exit__方法中加入print(exc_type, exc_val, exc_tb)
得到如下結果:
<class 'ZeroDivisionError'> division by zero <traceback object at 0x00000000032BADC8>
大家會問到追蹤信息是什麼呢?其實大家天天見....當你代碼錯誤了,提示哪一行有問題的時候,這個幫你定位的東西,就是追蹤信息。
想看到追蹤信息需要引入一個模塊,traceback
繼續在__exit__中添加這兩行信息
import traceback
print(traceback.extract_tb(exc_tb))
output:
[('E:/Python/xxxx/b.py', 21, '<module>', 'raise ValueError')]
上面個list什麼意思呢?錯誤的文件,錯誤的行號,文件類型,錯誤的語句
是不是吊炸天?好了今天就學到這裡,碎覺