bcb异常处理显示错误行号_python基础篇:错误和异常
在前面介紹Python語法的過程中,我們已經(jīng)接觸到了解釋器給的錯(cuò)誤和異常,但并沒有詳細(xì)講解它們。現(xiàn)在我們就全面的來學(xué)習(xí)Python是對(duì)語法錯(cuò)誤等錯(cuò)誤進(jìn)行定義和處理的,這包括至少有兩種可以區(qū)分的錯(cuò)誤,它們是語法錯(cuò)誤和異常。
語法錯(cuò)誤
Python的語法錯(cuò)誤就是不符合Python語法的錯(cuò)誤,又稱為解析錯(cuò)誤。這種錯(cuò)誤是初學(xué)Python對(duì)語法不是很熟悉時(shí)經(jīng)常犯的。比如下面的例子:
解釋器在解釋上面的代碼時(shí),就會(huì)發(fā)現(xiàn)表達(dá)式2 == 3后面少了一個(gè)冒號(hào):,這時(shí)它就會(huì)報(bào)出一個(gè)錯(cuò)誤SyntaxError: invalid syntax,并且輸出出現(xiàn)語法錯(cuò)誤的那一行,并顯示一個(gè)“箭頭”,指向這行里面檢測(cè)到第一個(gè)錯(cuò)誤。 錯(cuò)誤是由箭頭指示的位置上面的 token 引起的(或者至少是在這里被檢測(cè)出的)。文件名和行號(hào)也會(huì)被輸出,以便輸入來自腳本文件時(shí)你能知道去哪檢查。
解釋器這樣報(bào)出的好處是:
(1)告訴我們哪一行代碼出錯(cuò)了;
(2)錯(cuò)誤的類型是什么。
這樣非常有利于我們排除錯(cuò)誤,修正程序。
異常(Exception)
如果我們對(duì)語法很熟悉,寫出來的代碼在語法上都是正確的,但也不能保證在執(zhí)行時(shí)程序不會(huì)引發(fā)錯(cuò)誤。在執(zhí)行時(shí)檢測(cè)到的錯(cuò)誤被稱為異常,異常不一定會(huì)導(dǎo)致嚴(yán)重后果,但我們不在代碼中對(duì)它們進(jìn)行處理,就可能會(huì)導(dǎo)致程序中斷執(zhí)行。下面是一些常見的錯(cuò)誤異常信息:
我們看到,異常有不同的類型,其類型名稱會(huì)作為錯(cuò)誤信息的一部分中打印出來,上述示例中的異常類型分別是:ZeroDivisionError,NameError和TypeError。對(duì)于所有內(nèi)置異常,打印出來的字符串是內(nèi)置異常的名稱。對(duì)于用戶定義的異常則不一定如此,但我們自定義異常時(shí)最好按照內(nèi)置異常那樣去定義,這是一個(gè)很有用的規(guī)范。標(biāo)準(zhǔn)的異常類型是內(nèi)置的標(biāo)識(shí)符,而不是保留關(guān)鍵字。
打印出來的異常名稱后面是異常發(fā)生的原因。錯(cuò)誤信息的前一部分以堆棧回溯的形式顯示發(fā)生異常時(shí)代碼的上下文。一般它包含列出源代碼行的堆棧回溯;但是它不會(huì)顯示從標(biāo)準(zhǔn)輸入中讀取的行。
Python內(nèi)置了很多異常,它們都從BaseException繼承而來,下面是內(nèi)置異常的繼承關(guān)系:
Python錯(cuò)誤處理和異常處理
異常處理
既然程序會(huì)拋出異常,那我們就可以編寫代碼處理這些異常。先看下面的例子,它會(huì)讓用戶一直輸入,直到輸入的是一個(gè)有效的整數(shù)。我們也可以使用Control-C來中斷程序;這個(gè)Control-C引起的中斷會(huì)引發(fā) KeyboardInterrupt 異常。
當(dāng)我們輸入a時(shí),它不能轉(zhuǎn)換成整數(shù)就會(huì)報(bào)錯(cuò)異常ValueError。轉(zhuǎn)換為整數(shù)的那條語句報(bào)出了異常,它后面的語句就不再執(zhí)行,而是跳到except那里去執(zhí)行它里面的語句。
try語句的工作原理如下:
- 首先,執(zhí)行try 子句,即try和except關(guān)鍵詞之間的(一行或多行)語句;
- 如果沒有發(fā)生異常,則跳過except子句并完成try子句的執(zhí)行;
- 如果執(zhí)行try子句是發(fā)生了異常,則跳過該子句的剩下部分。然后,去匹配異常的類型和except關(guān)鍵字后面的異常,如果異常類型匹配則執(zhí)行except子句,之后繼續(xù)執(zhí)行try語句后面的代碼。
- 如果發(fā)生的異常和except后面的異常不匹配,則將其傳遞到外部的try語句,如果沒有找到處理代碼,則它是一個(gè)未處理異常,執(zhí)行將停止并顯示錯(cuò)誤信息。
一個(gè)try語句可以有多個(gè)except子句,以便不同的異常用不同的處理程序進(jìn)行處理。每次遇到異常最多會(huì)執(zhí)行一個(gè)except子句,也就是說,處理程序只處理相應(yīng)的異常,而不處理同一try語句內(nèi)其它處理程序的異常。但是,一個(gè)except子句可以將多個(gè)異常包含在一個(gè)元組內(nèi),例如:
異常都是繼承于BaseException,如果except子句中的類和發(fā)生的異常是同一個(gè)類,或者是異常的基類(父類),則異常和except子句中的類是兼容的。但是,反過來則不成立。我們看看下面的代碼,它將一次打印B,C,D。
如果我把 except 子句顛倒過來,把 except B 放到第一個(gè),猜猜它將會(huì)打印出什么?答案是它將打印 B,B,B。也就是第一個(gè)匹配的 except 子句被觸發(fā),因?yàn)锽是C、D的父類。
最后的 except 子句可以省略異常名稱,以用作通配符匹配所有的異常。這個(gè)要小心使用,因?yàn)檫@種方式很容易掩蓋真正的編程錯(cuò)誤!但是它可用于打印錯(cuò)誤消息,然后重新引發(fā)異常(同樣允許調(diào)用者處理異常):
try 語句有一個(gè)可選的 else 子句,在使用時(shí)它必須放在所有的 except 子句后面。對(duì)于在try 子句不引發(fā)異常時(shí)必須執(zhí)行的代碼來說很有用。例如:
使用else子句的好處是,它避免了意外捕獲由else子句引發(fā)的異常。也就是說,程序中我們只想捕獲open引發(fā)的異常,而不捕獲f.readlines()引發(fā)的錯(cuò)誤。
異常在拋出時(shí)可能具有關(guān)聯(lián)的值,稱為異常參數(shù)。參數(shù)的存在和類型取決于異常類型。
except子句可以在異常名稱后面指定一個(gè)變量,這個(gè)變量就是該異常的實(shí)例,它的參數(shù)存儲(chǔ)在instance.args中。為了方便起見,異常實(shí)例定義了__str__(),因此可以直接打印參數(shù)而無需引用.args。也可以在拋出之前首先實(shí)例化異常,并根據(jù)需要向其添加任何屬性。:
異常處理程序不僅可以處理try子句中遇到的異常,還可以處理try子句中調(diào)用的函數(shù)的內(nèi)部發(fā)生的異常,例如:
做什么事情都需要不斷地堅(jiān)持下去,編程也一樣。現(xiàn)在python語言十分火熱,職場(chǎng)對(duì)python的需求也很高,薪資待遇都很棒。所以希望大家能夠堅(jiān)持學(xué)習(xí),‘剩’者為王,堅(jiān)持下來的人才有資格稱王。如果你覺得本文對(duì)你的學(xué)習(xí)有幫助的話,不妨點(diǎn)個(gè)關(guān)注,我會(huì)持續(xù)更新。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的bcb异常处理显示错误行号_python基础篇:错误和异常的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: lnmp 清除mysql日志,军哥LNM
- 下一篇: 【ES9(2018)】for await