MyPython--进阶篇--异常
Python使用被稱為對象的特殊對象來管理程序執行期間發生的錯誤。每當發生讓pthon不知所措的錯誤時,他都會創建一個異常對象。如果你編寫了處理該異常的代碼,程序將繼續運行,否則程序將停止并顯示一個traceback,其中包含有關異常的報告。
異常是使用try-except代碼塊來處理的。代碼塊讓python執行指定的操作,同時告訴python發生異常時怎么辦。
處理ZeroDivisionError異常
將一個數字除以零
print(1/0) #報以下錯誤 Traceback (most recent call last):File "D:/pythontest/pycharmt/day9/pitest.py", line 41, in <module>print(1/0) ZeroDivisionError: division by zero這種情況下python停止運行并告訴你引發了哪種異常,ZerDivisionError錯誤是一個異常對象。我們可以增加代碼防止這種情況
try:print(1/0) except ZeroDivisionError:print('no zero')使用try-except代碼塊來處理可能觸發的異常。將可能出錯的代碼放到try內,在except中放入出錯后希望運行的代碼。如果沒有出錯,就跳過except代碼中的內容
else 代碼塊
通過將可能會引發錯誤的代碼放到代碼塊tr-except中,可提高這個程序抵御錯誤的能力。有賴于try代碼成功執行的代碼都應該放到else里?
while 1:num_1 = input('enter first num ')num_2 = input('enter second num')try:print(int(num_1)/int(num_2))except ZeroDivisionError:print('no zero ')else:answer = int(num_1)/int(num_2)將可能引發錯誤的代碼放入try中,將對觸發錯誤代碼后執行的放到except中,將try代碼執行成功后要執行的放在else代碼塊中
通過預測可能發生錯誤的代碼,可編寫健壯的程序,他們即便面臨無效數據或缺少資源,也能繼續運行,從而能抵御無意的用戶錯誤和惡意的攻擊
處理FileNotFoundError異常
來讀取一個不存在的文件
with open('cc.txt') as file_object:file_txt = file_object.read() Traceback (most recent call last):File "D:/python/pycharmtest/day12/filetest.py", line 15, in <module>with open('cc.txt') as file_object: FileNotFoundError: [Errno 2] No such file or directory: 'cc.txtpython找不到要打開的文件,于是創建了FileNotFoundError對相關,這個錯誤時open產生的
ry:with open('cc.txt') as file_object:file_txt = file_object.read() except FileNotFoundError:print('file not found')分析文本
with open('blog.txt')as file_object: # cont = '' # try: # contents = file_object.read() # for x in contents: # x = ''.join(x.split(' ')) # cont += x.strip() # except UnicodeDecodeError: # print('編碼錯誤') # print(cont) # print(len(cont))使用多個文件
def file_count(file_name):try:with open(file_name) as file_object:contents = file_object.read()except FileNotFoundError:print('%s is not found'%file_name)else:content = ''.join(contents.split())print('%s count %s'%(file_name,len(content))) file_name = ['blog.txt','pi.txt','cc.txt'] for x in file_name:file_count(x)輸出
blog.txt count 20 pi.txt count 1197 cc.txt is not found失敗時一聲不吭
try:with open('no.txt') as file_object:contents = file_object.read() except FileNotFoundError:pass else:print(len(contents.split()))在找不到文件時pass什么都不做,pass也充當一個占位符的作用
ValueError
while 1:num_1 = input('enter frist num')num_2 = input('enter second num')try:answer = int(num_1)/int(num_2)except ValueError:print('no chr')else:answer = int(num_1)/int(num_2)print(answer)?記錄錯誤
如果不捕獲錯誤,自然還可以讓python解釋器來打印處錯誤堆棧,但程序也被結束了。既然我們能捕獲錯誤,就可以把錯誤堆棧打印出來,然后分析錯誤原因,同時讓程序繼續執行下去?
python內置的logging 模塊可以非常容易地記錄錯誤信息:
import loggingdef bar1(n):return 10/n def bar2(n):return bar1(n)*2 def main():try:bar2(0)except Exception as e:logging.exception(e) main() print('end')同樣出錯,但程序打印完錯誤信息后會繼續執行,并正常退出
ERROR:root:division by zero end Traceback (most recent call last):File "D:/pythontest/pycharmt/senior/errortest.py", line 9, in mainbar2(0)File "D:/pythontest/pycharmt/senior/errortest.py", line 6, in bar2return bar1(n)*2File "D:/pythontest/pycharmt/senior/errortest.py", line 4, in bar1return 10/n ZeroDivisionError: division by zero拋出錯誤
因為錯誤是class,捕獲一個錯誤就是捕獲到該class的一個實例。因此,錯誤并不是憑空產生的,而是有意創建并拋出的。python的內置函數會拋出很多類型的錯誤,我們自己編寫的函數也可以
如果要拋出錯誤,首先要根據需要,定義一個錯誤的lclass,選擇好繼承關系,然后用raise語句拋出一個錯誤的實例
class FooError(ValueError):'''錯誤的類,選擇繼承關系'''pass def foo(s):if s ==0:raise FooError('invalid value : %s' % s)#拋出return 10/s foo(0)執行后,我們最后跟蹤對自己定義的錯誤
Traceback (most recent call last):File "D:/pythontest/pycharmt/senior/errortest.py", line 20, in <module>foo(0)File "D:/pythontest/pycharmt/senior/errortest.py", line 18, in fooraise FooError('invalid value : %s' % s) __main__.FooError: invalid value : 0只有必要的時候才定義我們自己的錯誤類型,如果可以你選擇python已有的內置的錯誤類型(比如ValueError,TypeError),盡量使用python內置的錯誤類型
決不能把一個IOError轉換成毫不相干的ValueError
在文檔中寫清楚可能會拋出那些錯誤,依舊錯誤產生的原因
調試
再議logging
把print()替換為logging是檢查錯誤的第三章方式,和assert比,logging不會拋出錯誤,而且可以輸出到文件
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
轉載于:https://www.cnblogs.com/notJoke/p/5831854.html
總結
以上是生活随笔為你收集整理的MyPython--进阶篇--异常的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sendmail dead but su
- 下一篇: rsync同步配制