MyPython--进阶篇--异常
Python使用被稱(chēng)為對(duì)象的特殊對(duì)象來(lái)管理程序執(zhí)行期間發(fā)生的錯(cuò)誤。每當(dāng)發(fā)生讓pthon不知所措的錯(cuò)誤時(shí),他都會(huì)創(chuàng)建一個(gè)異常對(duì)象。如果你編寫(xiě)了處理該異常的代碼,程序?qū)⒗^續(xù)運(yùn)行,否則程序?qū)⑼V共@示一個(gè)traceback,其中包含有關(guān)異常的報(bào)告。
異常是使用try-except代碼塊來(lái)處理的。代碼塊讓python執(zhí)行指定的操作,同時(shí)告訴python發(fā)生異常時(shí)怎么辦。
處理ZeroDivisionError異常
將一個(gè)數(shù)字除以零
print(1/0) #報(bào)以下錯(cuò)誤 Traceback (most recent call last):File "D:/pythontest/pycharmt/day9/pitest.py", line 41, in <module>print(1/0) ZeroDivisionError: division by zero這種情況下python停止運(yùn)行并告訴你引發(fā)了哪種異常,ZerDivisionError錯(cuò)誤是一個(gè)異常對(duì)象。我們可以增加代碼防止這種情況
try:print(1/0) except ZeroDivisionError:print('no zero')使用try-except代碼塊來(lái)處理可能觸發(fā)的異常。將可能出錯(cuò)的代碼放到try內(nèi),在except中放入出錯(cuò)后希望運(yùn)行的代碼。如果沒(méi)有出錯(cuò),就跳過(guò)except代碼中的內(nèi)容
else 代碼塊
通過(guò)將可能會(huì)引發(fā)錯(cuò)誤的代碼放到代碼塊tr-except中,可提高這個(gè)程序抵御錯(cuò)誤的能力。有賴(lài)于try代碼成功執(zhí)行的代碼都應(yīng)該放到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)將可能引發(fā)錯(cuò)誤的代碼放入try中,將對(duì)觸發(fā)錯(cuò)誤代碼后執(zhí)行的放到except中,將try代碼執(zhí)行成功后要執(zhí)行的放在else代碼塊中
通過(guò)預(yù)測(cè)可能發(fā)生錯(cuò)誤的代碼,可編寫(xiě)健壯的程序,他們即便面臨無(wú)效數(shù)據(jù)或缺少資源,也能繼續(xù)運(yùn)行,從而能抵御無(wú)意的用戶錯(cuò)誤和惡意的攻擊
處理FileNotFoundError異常
來(lái)讀取一個(gè)不存在的文件
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找不到要打開(kāi)的文件,于是創(chuàng)建了FileNotFoundError對(duì)相關(guān),這個(gè)錯(cuò)誤時(shí)open產(chǎn)生的
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('編碼錯(cuò)誤') # print(cont) # print(len(cont))使用多個(gè)文件
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失敗時(shí)一聲不吭
try:with open('no.txt') as file_object:contents = file_object.read() except FileNotFoundError:pass else:print(len(contents.split()))在找不到文件時(shí)pass什么都不做,pass也充當(dāng)一個(gè)占位符的作用
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)?記錄錯(cuò)誤
如果不捕獲錯(cuò)誤,自然還可以讓python解釋器來(lái)打印處錯(cuò)誤堆棧,但程序也被結(jié)束了。既然我們能捕獲錯(cuò)誤,就可以把錯(cuò)誤堆棧打印出來(lái),然后分析錯(cuò)誤原因,同時(shí)讓程序繼續(xù)執(zhí)行下去?
python內(nèi)置的logging 模塊可以非常容易地記錄錯(cuò)誤信息:
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')同樣出錯(cuò),但程序打印完錯(cuò)誤信息后會(huì)繼續(xù)執(zhí)行,并正常退出
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拋出錯(cuò)誤
因?yàn)殄e(cuò)誤是class,捕獲一個(gè)錯(cuò)誤就是捕獲到該class的一個(gè)實(shí)例。因此,錯(cuò)誤并不是憑空產(chǎn)生的,而是有意創(chuàng)建并拋出的。python的內(nèi)置函數(shù)會(huì)拋出很多類(lèi)型的錯(cuò)誤,我們自己編寫(xiě)的函數(shù)也可以
如果要拋出錯(cuò)誤,首先要根據(jù)需要,定義一個(gè)錯(cuò)誤的lclass,選擇好繼承關(guān)系,然后用raise語(yǔ)句拋出一個(gè)錯(cuò)誤的實(shí)例
class FooError(ValueError):'''錯(cuò)誤的類(lèi),選擇繼承關(guān)系'''pass def foo(s):if s ==0:raise FooError('invalid value : %s' % s)#拋出return 10/s foo(0)執(zhí)行后,我們最后跟蹤對(duì)自己定義的錯(cuò)誤
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只有必要的時(shí)候才定義我們自己的錯(cuò)誤類(lèi)型,如果可以你選擇python已有的內(nèi)置的錯(cuò)誤類(lèi)型(比如ValueError,TypeError),盡量使用python內(nèi)置的錯(cuò)誤類(lèi)型
決不能把一個(gè)IOError轉(zhuǎn)換成毫不相干的ValueError
在文檔中寫(xiě)清楚可能會(huì)拋出那些錯(cuò)誤,依舊錯(cuò)誤產(chǎn)生的原因
調(diào)試
再議logging
把print()替換為logging是檢查錯(cuò)誤的第三章方式,和assert比,logging不會(huì)拋出錯(cuò)誤,而且可以輸出到文件
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/notJoke/p/5831854.html
總結(jié)
以上是生活随笔為你收集整理的MyPython--进阶篇--异常的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: sendmail dead but su
- 下一篇: rsync同步配制