08-Python3 錯(cuò)誤和異常

一顷蟀、Python3 錯(cuò)誤和異常

Python有兩種錯(cuò)誤很容易辨認(rèn):語(yǔ)法錯(cuò)誤和異常丐膝。

  • 語(yǔ)法錯(cuò)誤

Python 的語(yǔ)法錯(cuò)誤或者稱(chēng)之為解析錯(cuò),是初學(xué)者經(jīng)常碰到的淫半,如下實(shí)例>

while True print('Hello world')
  File "<stdin>", line 1, in ?
    while True print('Hello world')
                   ^
SyntaxError: invalid syntax

這個(gè)例子中溃槐,函數(shù) print() 被檢查到有錯(cuò)誤,是它前面缺少了一個(gè)冒號(hào)(:)科吭。
語(yǔ)法分析器指出了出錯(cuò)的一行昏滴,并且在最先找到的錯(cuò)誤的位置標(biāo)記了一個(gè)小小的箭頭。

  • 異常

即便Python程序的語(yǔ)法是正確的对人,在運(yùn)行它的時(shí)候谣殊,也有可能發(fā)生錯(cuò)誤。運(yùn)行期檢測(cè)到的錯(cuò)誤被稱(chēng)為異常牺弄。大多數(shù)的異常都不會(huì)被程序處理姻几,都以錯(cuò)誤信息的形式展現(xiàn)在這里:

>>> 10 * (1/0)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ZeroDivisionError: division by zero
>>> 4 + spam*3
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
NameError: name 'spam' is not defined
>>> '2' + 2
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: Can't convert 'int' object to str implicitly

異常以不同的類(lèi)型出現(xiàn),這些類(lèi)型都作為信息的一部分打印出來(lái): 例子中的類(lèi)型有 ZeroDivisionError势告,NameError 和 TypeError蛇捌。
錯(cuò)誤信息的前面部分顯示了異常發(fā)生的上下文,并以調(diào)用棧的形式顯示具體信息咱台。
程序執(zhí)行過(guò)程中出現(xiàn)問(wèn)題導(dǎo)致程序無(wú)法執(zhí)行

  • 異常的分類(lèi):
    1络拌、程序遇到邏輯或算法錯(cuò)誤

    2、運(yùn)行過(guò)程中計(jì)算機(jī)錯(cuò)誤:內(nèi)存不夠或者io錯(cuò)誤

  • 異常的步驟:
    1回溺、異常產(chǎn)生盒音,檢查到錯(cuò)誤且解釋器認(rèn)為是異常,拋出異常

    2馅而、異常處理,異常處理譬圣,截獲異常瓮恭,系統(tǒng)忽略或者終止程序處理異常


    image.png
    image.png

二、異常處理

  • 1.異常處理的定義

python解釋器檢測(cè)到錯(cuò)誤湖笨,觸發(fā)異常(也允許程序員自己觸發(fā)異常)
程序員編寫(xiě)特定的代碼祷嘶,專(zhuān)門(mén)用來(lái)捕捉這個(gè)異常(這段代碼與程序邏輯無(wú)關(guān),與異常處理有關(guān))
如果捕捉成功則進(jìn)入另外一個(gè)處理分支愈诚,執(zhí)行你為其定制的邏輯登澜,使程序不會(huì)崩潰阔挠,這就是異常處理

  • 2.異常處理的意義

python解析器去執(zhí)行程序,檢測(cè)到了一個(gè)錯(cuò)誤時(shí)脑蠕,觸發(fā)異常购撼,異常觸發(fā)后且沒(méi)被處理的情況下,程序就在當(dāng)前異常處終止谴仙,后面的代碼不會(huì)運(yùn)行迂求,所以你必須提供一種異常處理機(jī)制來(lái)增強(qiáng)你程序的健壯性與容錯(cuò)性

以下例子中,讓用戶(hù)輸入一個(gè)合法的整數(shù)晃跺,但是允許用戶(hù)中斷這個(gè)程序(使用 Control-C 或者操作系統(tǒng)提供的方法)揩局。用戶(hù)中斷的信息會(huì)引發(fā)一個(gè) KeyboardInterrupt 異常。

>>> while True:
        try:
            x = int(input("Please enter a number: "))
            break
        except ValueError:
            print("Oops!  That was no valid number.  Try again   ")

try語(yǔ)句按照如下方式工作掀虎;

  • 首先凌盯,執(zhí)行try子句(在關(guān)鍵字try和關(guān)鍵字except之間的語(yǔ)句)
  • 如果沒(méi)有異常發(fā)生,忽略except子句烹玉,try子句執(zhí)行后結(jié)束驰怎。
  • 如果在執(zhí)行try子句的過(guò)程中發(fā)生了異常,那么try子句余下的部分將被忽略春霍。如果異常的類(lèi)型和 except 之后的名稱(chēng)相符砸西,那么對(duì)應(yīng)的except子句將被執(zhí)行。最后執(zhí)行 try 語(yǔ)句之后的代碼址儒。
  • 如果一個(gè)異常沒(méi)有與任何的except匹配芹枷,那么這個(gè)異常將會(huì)傳遞給上層的try中。

一個(gè) try 語(yǔ)句可能包含多個(gè)except子句莲趣,分別來(lái)處理不同的特定的異常鸳慈。最多只有一個(gè)分支會(huì)被執(zhí)行。
處理程序?qū)⒅会槍?duì)對(duì)應(yīng)的try子句中的異常進(jìn)行處理喧伞,而不是其他的 try 的處理程序中的異常走芋。
一個(gè)except子句可以同時(shí)處理多個(gè)異常,這些異常將被放在一個(gè)括號(hào)里成為一個(gè)元組潘鲫,例如:

except (RuntimeError, TypeError, NameError):
pass
最后一個(gè)except子句可以忽略異常的名稱(chēng)翁逞,它將被當(dāng)作通配符使用。你可以使用這種方法打印一個(gè)錯(cuò)誤信息溉仑,然后再次把異常拋出挖函。

import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except OSError as err:
    print("OS error: {0}".format(err))
except ValueError:
    print("Could not convert data to an integer.")
except:
    print("Unexpected error:", sys.exc_info()[0])
    raise

try except 語(yǔ)句還有一個(gè)可選的else子句,如果使用這個(gè)子句浊竟,那么必須放在所有的except子句之后怨喘。這個(gè)子句將在try子句沒(méi)有發(fā)生任何異常的時(shí)候執(zhí)行津畸。例如:

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except IOError:
        print('cannot open', arg)
    else:
        print(arg, 'has', len(f.readlines()), 'lines')
        f.close()

使用 else 子句比把所有的語(yǔ)句都放在 try 子句里面要好,這樣可以避免一些意想不到的必怜、而except又沒(méi)有捕獲的異常肉拓。

異常處理并不僅僅處理那些直接發(fā)生在try子句中的異常,而且還能處理子句中調(diào)用的函數(shù)(甚至間接調(diào)用的函數(shù))里拋出的異常梳庆。例如:

>>> def this_fails():
        x = 1/0
   
>>> try:
        this_fails()
    except ZeroDivisionError as err:
        print('Handling run-time error:', err)
   
Handling run-time error: int division or modulo by zero

三暖途、常見(jiàn)的異常

  • AttributeError 試圖訪問(wèn)一個(gè)對(duì)象沒(méi)有的屬性,比如foo.x靠益,但是foo沒(méi)有屬性x
  • IOError 輸入/輸出異常丧肴;基本上是無(wú)法打開(kāi)文件
  • ImportError 無(wú)法引入模塊或包;基本上是路徑問(wèn)題或名稱(chēng)錯(cuò)誤
  • IndentationError 語(yǔ)法錯(cuò)誤(的子類(lèi)) 胧后;代碼沒(méi)有正確對(duì)齊
  • IndexError 下標(biāo)索引超出序列邊界芋浮,比如當(dāng)x只有三個(gè)元素,卻試圖訪問(wèn)x[5]
  • KeyError 試圖訪問(wèn)字典里不存在的鍵
  • KeyboardInterrupt Ctrl+C被按下
  • NameError 嘗試訪問(wèn)一個(gè)沒(méi)有申明的變量
  • SyntaxError Python代碼非法壳快,代碼不能編譯(個(gè)人認(rèn)為這是語(yǔ)法錯(cuò)誤纸巷,寫(xiě)錯(cuò)了)
  • TypeError 傳入對(duì)象類(lèi)型與要求的不符合
  • UnboundLocalError 試圖訪問(wèn)一個(gè)還未被設(shè)置的局部變量,基本上是由于另有一個(gè)同名的全局變量眶痰,導(dǎo)致你以為正在訪問(wèn)它
  • ValueError 傳入一個(gè)調(diào)用者不期望的值瘤旨,即使值的類(lèi)型是正確的
補(bǔ)充:

異常名稱(chēng) 描述
BaseException 所有異常的基類(lèi)
SystemExit 解釋器請(qǐng)求退出
KeyboardInterrupt 用戶(hù)中斷執(zhí)行(通常是輸入^C)
Exception 常規(guī)錯(cuò)誤的基類(lèi)
StopIteration 迭代器沒(méi)有更多的值
GeneratorExit 生成器(generator)發(fā)生異常來(lái)通知退出
StandardError 所有的內(nèi)建標(biāo)準(zhǔn)異常的基類(lèi)
ArithmeticError 所有數(shù)值計(jì)算錯(cuò)誤的基類(lèi)
FloatingPointError 浮點(diǎn)計(jì)算錯(cuò)誤
OverflowError 數(shù)值運(yùn)算超出最大限制
ZeroDivisionError 除(或取模)零 (所有數(shù)據(jù)類(lèi)型)
AssertionError 斷言語(yǔ)句失敗
AttributeError 對(duì)象沒(méi)有這個(gè)屬性
EOFError 沒(méi)有內(nèi)建輸入,到達(dá)EOF 標(biāo)記
EnvironmentError 操作系統(tǒng)錯(cuò)誤的基類(lèi)
IOError 輸入/輸出操作失敗
OSError 操作系統(tǒng)錯(cuò)誤
WindowsError 系統(tǒng)調(diào)用失敗
ImportError 導(dǎo)入模塊/對(duì)象失敗
LookupError 無(wú)效數(shù)據(jù)查詢(xún)的基類(lèi)
IndexError 序列中沒(méi)有此索引(index)
KeyError 映射中沒(méi)有這個(gè)鍵
MemoryError 內(nèi)存溢出錯(cuò)誤(對(duì)于Python 解釋器不是致命的)
NameError 未聲明/初始化對(duì)象 (沒(méi)有屬性)
UnboundLocalError 訪問(wèn)未初始化的本地變量
ReferenceError 弱引用(Weak reference)試圖訪問(wèn)已經(jīng)垃圾回收了的對(duì)象
RuntimeError 一般的運(yùn)行時(shí)錯(cuò)誤
NotImplementedError 尚未實(shí)現(xiàn)的方法
SyntaxError Python 語(yǔ)法錯(cuò)誤
IndentationError 縮進(jìn)錯(cuò)誤
TabError Tab 和空格混用
SystemError 一般的解釋器系統(tǒng)錯(cuò)誤
TypeError 對(duì)類(lèi)型無(wú)效的操作
ValueError 傳入無(wú)效的參數(shù)
UnicodeError Unicode 相關(guān)的錯(cuò)誤
UnicodeDecodeError Unicode 解碼時(shí)的錯(cuò)誤
UnicodeEncodeError Unicode 編碼時(shí)錯(cuò)誤
UnicodeTranslateError Unicode 轉(zhuǎn)換時(shí)錯(cuò)誤
Warning 警告的基類(lèi)
DeprecationWarning 關(guān)于被棄用的特征的警告
FutureWarning 關(guān)于構(gòu)造將來(lái)語(yǔ)義會(huì)有改變的警告
OverflowWarning 舊的關(guān)于自動(dòng)提升為長(zhǎng)整型(long)的警告
PendingDeprecationWarning 關(guān)于特性將會(huì)被廢棄的警告
RuntimeWarning 可疑的運(yùn)行時(shí)行為(runtime behavior)的警告
SyntaxWarning 可疑的語(yǔ)法的警告
UserWarning 用戶(hù)代碼生成的警告</pre>

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市竖伯,隨后出現(xiàn)的幾起案子存哲,更是在濱河造成了極大的恐慌,老刑警劉巖七婴,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件祟偷,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡打厘,警方通過(guò)查閱死者的電腦和手機(jī)修肠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)户盯,“玉大人嵌施,你說(shuō)我怎么就攤上這事∶а迹” “怎么了吗伤?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)硫眨。 經(jīng)常有香客問(wèn)我足淆,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任缸浦,我火速辦了婚禮,結(jié)果婚禮上氮兵,老公的妹妹穿的比我還像新娘裂逐。我一直安慰自己,他們只是感情好泣栈,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布卜高。 她就那樣靜靜地躺著,像睡著了一般南片。 火紅的嫁衣襯著肌膚如雪掺涛。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,462評(píng)論 1 302
  • 那天疼进,我揣著相機(jī)與錄音薪缆,去河邊找鬼。 笑死伞广,一個(gè)胖子當(dāng)著我的面吹牛拣帽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嚼锄,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼减拭,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了区丑?” 一聲冷哼從身側(cè)響起拧粪,我...
    開(kāi)封第一講書(shū)人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎沧侥,沒(méi)想到半個(gè)月后可霎,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡正什,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年啥纸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片婴氮。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡斯棒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出主经,到底是詐尸還是另有隱情荣暮,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布罩驻,位于F島的核電站穗酥,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜砾跃,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一骏啰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧抽高,春花似錦判耕、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至碳竟,卻和暖如春草丧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背莹桅。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工昌执, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人统翩。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓仙蚜,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親厂汗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子委粉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容