一.引入:
Python是解釋型語言,會整體掃描一下代碼,如果有語法錯誤,則整個程序完全不會執行。如下:
def myfun():
print('哈哈哈哈哈哈哈')
print(‘嘻嘻嘻嘻')#這裏是中文的括號
print('嘿嘿')
myfun()
沒有語法錯誤的時候一行行檢查,直到掃描到其他錯誤的位置,停止執行。(在掃描到錯誤之前正確的代碼還是會執行的)如下:
def myfun():
print('哈哈哈哈哈哈哈')
b = 'hello' + 15#類型錯誤
print(b)
print('嘿嘿')
myfun()
python中所有的異常都是繼承自BaseException,分爲四大類:
類型 | 描述 |
SystemExit | python退出異常 |
Keyboardlnterrupt | 鍵盤打斷(ctrl + c) |
GeneratorExit | 生成器退出 |
Exception | 普通異常 |
二.異常
三.try......except捕獲異常:
try:
with open('a.txt','r') as f:
f.read()
except: #在pycharm中會有波浪線,因爲沒有加具體的異常
print('沒有找到又怎麼樣呢?')#當a.txt不存在時會打印
#運行結果:
沒有找到又怎麼樣呢?
當try中的代碼沒有報錯時,except就不會執行,當try中的代碼出錯時,會執行except中的代碼
try:
a = 0
b = 1/a
except:
print('沒寫錯!')
捕獲具體的異常:
try:
with open('a.txt','r') as f:
f.read()
except FileNotFoundError:#增加了具體的異常類型
print('沒有找到又怎麼樣呢?')#當a.txt不存在時會打印
當增加了a = 0, b = 1/a這個錯誤的時候,在with之後,它不會被捕捉到,因爲with已經出錯,直接執行except;如果a = 0, b = 1/a,放在with之前,則會報錯
try:
with open('a.txt','r') as f:
f.read()
a = 0
b = 1/a
except FileNotFoundError:
print('沒有找到又怎麼樣呢?')#當a.txt不存在時會打印
#運行結果
沒有找到又怎麼樣呢?
再增加一個異常:
try:
a = 0
b = 1 / a
with open('a.txt','r') as f:
f.read()
except FileNotFoundError:
print('沒有找到又怎麼樣呢?')#當a.txt不存在時會打印
except ZeroDivisionError:
print('這是分母爲0的一個錯誤')
#運行結果
這是分母爲0的一個錯誤
捕獲多種異常:
try:
raise TypeError('嘿嘿嘿,這是一個類型錯誤') #主動拋出一個異常
except FileNotFoundError:
print('沒有找到又怎麼樣呢?')#當a.txt不存在時會打印
except ZeroDivisionError:
print('這是分母爲0的一個錯誤')
except Exception as e:
print(e)#打印出主動拋出的異常
主動拋出異常:
def myfunc(num):
if type(num) != int:
raise TypeError('不是數字')
return num * 10
print(myfunc('hello'))
運行結果:
四.更加豐富的結構
try:
except...:
else...: 在沒有錯誤的時候執行
finally: 無論如何都會執行
當報錯時:
def myfunc(num):
if type(num) != int:
raise TypeError('不是數字')
return num * 10
try:
print(myfunc('hello'))
except TypeError:
print('代碼出錯了')
else:
print('代碼沒有報錯')
finally:
print('不管怎樣,我finally都會執行')
#運行結果
代碼出錯了
不管怎樣,我finally都會執行
沒有報錯時:
def myfunc(num):
if type(num) != int:
raise TypeError('不是數字')
return num * 10
try:
print(myfunc(10))
except TypeError:
print('代碼出錯了')
else:
print('代碼沒有報錯')
finally:
print('不管怎樣,我finally都會執行')
#運行結果
100
代碼沒有報錯
不管怎樣,我finally都會執行
五.斷言
不使用斷言:
if not False:
raise Exception('條件不滿足')
使用斷言:
assert True #不拋出異常
assert False #拋出異常
例:
def myfunc(num):
assert type(num) == int #相當於 if type(num) != int: raise TypeError('不是數字')
return num * 10
print(myfunc('hello'))
運行結果:
六.自定義異常類型
class NameMustBeNanBeiError(Exception):
pass
def myfunc(name):
if name != '哈哈':
raise NameMustBeNanBeiError('必須要是哈哈哦~')
try:
print(myfunc('嘿嘿'))
except Exception as e:
print(e)
#運行結果:
必須要是哈哈哦~
練習1
如果我用w模式正常的打開了文件,然後write時候如果報錯呢?那麼我怎麼正常關閉文件?
import os
if not os.path.exists('my_tesr.txt'): # 判斷文件是否存在
file = open('my_test.txt', 'w+', encoding='utf-8')
try:
my_dict = {'name': 'xiaojiu'}
file.write(my_dict['name'])
except Exception as e:
print(e)
finally:
file.close()
print('文件正常關閉')
# 文件存在則不會運行try