python開發(fā)--異常

#! /usr/bin/env python
-*- coding:utf-8 -*-

'''
@Author:gcan
@Email:1528667112@qq.com
@Site:http://www.gcan.top
@File:exception.py
@Software:PyCharm
@Date:2018-05-14 22:48:40
@Version:1.0.0
'''

異常
Python使用被稱為異常 的特殊對(duì)象來管理程序執(zhí)行期間發(fā)生的錯(cuò)誤。每當(dāng)發(fā)生讓Python不知所措的錯(cuò)誤時(shí),它都會(huì)創(chuàng)建一個(gè)異常對(duì)象。如果你編寫了處理該異常的代碼猜憎,程序?qū)⒗^
續(xù)運(yùn)行;如果你未對(duì)異常進(jìn)行處理,程序?qū)⑼V股危@示一個(gè)traceback胰柑,其中包含有關(guān)異常的報(bào)告。
異常是使用try-except 代碼塊處理的爬泥。try-except 代碼塊讓Python執(zhí)行指定的操作柬讨,同時(shí)告訴Python發(fā)生異常時(shí)怎么辦。使用了try-except 代碼塊時(shí)袍啡,即便出現(xiàn)異常踩官,
程序也將繼續(xù)運(yùn)行:顯示你編寫的友好的錯(cuò)誤消息,而不是令用戶迷惑的traceback境输。

處理ZeroDivisionError 異常
下面來看一種導(dǎo)致Python引發(fā)異常的簡單錯(cuò)誤蔗牡。你可能知道不能將一個(gè)數(shù)字除以0,但我們還是讓Python這樣做吧: division.py

print(5/0)

顯然嗅剖,Python無法這樣做辩越,因此你將看到一個(gè)traceback:

Traceback (most recent call last):
  File "/Users/mm/study_python/my_python/five/exception.py", line 23, in <module>
    print(5/0)
ZeroDivisionError: division by zero

在上述traceback中,指出的錯(cuò)誤ZeroDivisionError 是一個(gè)異常對(duì)象信粮。Python無法按你的要求做時(shí)黔攒,就會(huì)創(chuàng)建這種對(duì)象。
在這種情況下强缘,Python將停止運(yùn)行程序督惰,并指出引發(fā)了哪種異常,而我們可根據(jù)這些信息對(duì)程序進(jìn)行修改旅掂。
下面我們將告訴Python姑丑,發(fā)生這種錯(cuò)誤時(shí)怎么辦;這樣,如果再次發(fā)生這樣的錯(cuò)誤辞友,我們就有備無患了。

使用try-except 代碼塊
當(dāng)你認(rèn)為可能發(fā)生了錯(cuò)誤時(shí),可編寫一個(gè)try-except 代碼塊來處理可能引發(fā)的異常称龙。你讓Python嘗試運(yùn)行一些代碼留拾,并告訴它如果這些代碼引發(fā)了指定的異常,該怎么辦鲫尊。 處理ZeroDivisionError 異常的try-except 代碼塊類似于下面這樣:

try:
    print(5/0)
except ZeroDivisionError:
    print("You can't divide by zero!")

我們將導(dǎo)致錯(cuò)誤的代碼行print(5/0) 放在了一個(gè)try 代碼塊中痴柔。如果try 代碼塊中的代碼運(yùn)行起來沒有問題,Python將跳過except 代碼塊;
如果try 代碼塊中的代碼導(dǎo)致了 錯(cuò)誤疫向,Python將查找這樣的except 代碼塊咳蔚,并運(yùn)行其中的代碼,即其中指定的錯(cuò)誤與引發(fā)的錯(cuò)誤相同搔驼。

try 代碼塊中的代碼引發(fā)了ZeroDivisionError 異常谈火,因此Python指出了該如何解決問題的except 代碼塊,并運(yùn)行其中的代碼舌涨。
這樣糯耍,用戶看到的是一條友 好的錯(cuò)誤消息,而不是traceback:

使用異常避免崩潰
發(fā)生錯(cuò)誤時(shí)囊嘉,如果程序還有工作沒有完成温技,妥善地處理錯(cuò)誤就尤其重要。這種情況經(jīng)常會(huì)出現(xiàn)在要求用戶提供輸入的程序中;如果程序能夠妥善地處理無效輸入扭粱,就能再提示用 戶提供有效輸入舵鳞,而不至于崩潰。
下面來創(chuàng)建一個(gè)只執(zhí)行除法運(yùn)算的簡單計(jì)算器:

print("Give me two numbers, and I'll divide them.")
print("Enter 'q' to quit.")
while True:
    first_number = input("\nFirst number: ")
    if first_number == 'q':
        break
    second_number = input("Second number: ")
    if second_number == 'q':
        break
    answer = int(first_number) / int(second_number)
    print(answer)

這個(gè)程序提示用戶輸入一個(gè)數(shù)字琢蛤,并將其存儲(chǔ)到變量first_number 中;如果用戶輸入的不是表示退出的q蜓堕,就再提示用戶輸入一個(gè)數(shù)字,并將其存儲(chǔ)到變 量second_number 中虐块。
接下來俩滥,我們計(jì)算這兩個(gè)數(shù)字的商(即answer)。這個(gè)程序沒有采取任何處理錯(cuò)誤的措施贺奠,因此讓它執(zhí)行除數(shù)為0的除法運(yùn)算時(shí)霜旧,它將崩潰:

程序崩潰可不好,但讓用戶看到traceback也不是好主意儡率。不懂技術(shù)的用戶會(huì)被它們搞糊涂挂据,而且如果用戶懷有惡意,他會(huì)通過traceback獲悉你不希望他知道的信息儿普。
例如崎逃,他將知 道你的程序文件的名稱,還將看到部分不能正確運(yùn)行的代碼眉孩。有時(shí)候个绍,訓(xùn)練有素的攻擊者可根據(jù)這些信息判斷出可對(duì)你的代碼發(fā)起什么樣的攻擊勒葱。

通過將可能引發(fā)錯(cuò)誤的代碼放在try-except 代碼塊中,可提高這個(gè)程序抵御錯(cuò)誤的能力巴柿。錯(cuò)誤是執(zhí)行除法運(yùn)算的代碼行導(dǎo)致的凛虽,因此我們需要將它放到try-except 代碼塊
中。這個(gè)示例還包含一個(gè)else 代碼塊;依賴于try 代碼塊成功執(zhí)行的代碼都應(yīng)放到else 代碼塊中:

print("Give me two numbers, and I'll divide them.")
print("Enter 'q' to quit.")
while True:
    first_number = input("\nFirst number: ")
    if first_number == 'q':
        break
    second_number = input("Second number: ")
    try:
        answer = int(first_number) / int(second_number)
    except ZeroDivisionError:
        print("You can't divide by 0!")
    else:
        print(answer)

我們讓Python嘗試執(zhí)行try 代碼塊中的除法運(yùn)算广恢,這個(gè)代碼塊只包含可能導(dǎo)致錯(cuò)誤的代碼凯旋。依賴于try 代碼塊成功執(zhí)行的代碼都放在else 代碼塊中;在這個(gè)示例中,
如果除法運(yùn)算成功钉迷,我們就使用else 代碼塊來打印結(jié)果至非。
except 代碼塊告訴Python,出現(xiàn)ZeroDivisionError 異常時(shí)該怎么辦糠聪。如果try 代碼塊因除零錯(cuò)誤而失敗荒椭,我們就打印一條友好的消息,告訴用戶如何避免這種錯(cuò)誤枷颊。
程序?qū)⒗^續(xù)運(yùn)行戳杀,用戶根本看不到traceback:

Give me two numbers, and I'll divide them.
Enter 'q' to quit.

First number: 22
Second number: 0
You can't divide by 0!

First number: q

try-except-else 代碼塊的工作原理大致如下:Python嘗試執(zhí)行try 代碼塊中的代碼;只有可能引發(fā)異常的代碼才需要放在try 語句中。
有時(shí)候夭苗,有一些僅在try 代碼塊成功 執(zhí)行時(shí)才需要運(yùn)行的代碼;這些代碼應(yīng)放在else 代碼塊中信卡。except 代碼塊告訴Python,如果它嘗試運(yùn)行try 代碼塊中的代碼時(shí)引發(fā)了指定的異常题造,該怎么辦傍菇。
通過預(yù)測(cè)可能發(fā)生錯(cuò)誤的代碼,可編寫健壯的程序界赔,它們即便面臨無效數(shù)據(jù)或缺少資源丢习,也能繼續(xù)運(yùn)行,從而能夠抵御無意的用戶錯(cuò)誤和惡意的攻擊淮悼。

處理FileNotFoundError 異常 使用文件時(shí)咐低,一種常見的問題是找不到文件:你要查找的文件可能在其他地方、文件名可能不正確或者這個(gè)文件根本就不存在袜腥。對(duì)于所有這些情形见擦,都可使用try-except 代碼
塊以直觀的方式進(jìn)行處理。 我們來嘗試讀取一個(gè)不存在的文件羹令。下面的程序嘗試讀取文件alice.txt的內(nèi)容鲤屡,但我沒有將這個(gè)文件存儲(chǔ)在alice.py所在的目錄中

filename = 'alice.txt'
with open(filename) as f_obj:
    contents = f_obj.read()
Traceback (most recent call last):
  File "/Users/mm/study_python/my_python/five/exception.py", line 119, in <module>
    with open(filename) as f_obj:
FileNotFoundError: [Errno 2] No such file or directory: 'alice.txt'

在上述traceback中,最后一行報(bào)告了FileNotFoundError 異常福侈,這是Python找不到要打開的文件時(shí)創(chuàng)建的異常酒来。
在這個(gè)示例中,這個(gè)錯(cuò)誤是函數(shù)open() 導(dǎo)致的肪凛,因此要處理 這個(gè)錯(cuò)誤堰汉,必須將try 語句放在包含open() 的代碼行之前:

filename = 'alice.txt'
try:
    with open(filename) as f_obj:
         contents = f_obj.read()
except FileNotFoundError:
    msg = "Sorry, the file " + filename + " does not exist."
    print(msg)

在這個(gè)示例中辽社,try 代碼塊引發(fā)FileNotFoundError 異常,因此Python找出與該錯(cuò)誤匹配的except 代碼塊衡奥,并運(yùn)行其中的代碼爹袁。最終的結(jié)果是顯示一條友好的錯(cuò)誤消息,而 不是traceback:
Sorry, the file alice.txt does not exist.
如果文件不存在矮固,這個(gè)程序什么都不做,因此錯(cuò)誤處理代碼的意義不大譬淳。下面來擴(kuò)展這個(gè)示例档址,看看在你使用多個(gè)文件時(shí),異常處理可提供什么樣的幫助邻梆。

決定報(bào)告哪些錯(cuò)誤
在什么情況下該向用戶報(bào)告錯(cuò)誤?在什么情況下又應(yīng)該在失敗時(shí)一聲不吭呢?如果用戶知道要分析哪些文件守伸,他們可能希望在有文件沒有分析時(shí)出現(xiàn)一條消息,將其中的原因告 訴他們浦妄。如果用戶只想看到結(jié)果尼摹,而并不知道要分析哪些文件,可能就無需在有些文件不存在時(shí)告知他們剂娄。向用戶顯示他不想看到的信息可能會(huì)降低程序的可用性蠢涝。Python的錯(cuò)誤 處理結(jié)構(gòu)讓你能夠細(xì)致地控制與用戶分享錯(cuò)誤信息的程度,要分享多少信息由你決定阅懦。
編寫得很好且經(jīng)過詳盡測(cè)試的代碼不容易出現(xiàn)內(nèi)部錯(cuò)誤和二,如語法或邏輯錯(cuò)誤,但只要程序依賴于外部因素耳胎,如用戶輸入惯吕、存在指定的文件、有網(wǎng)絡(luò)鏈接怕午,就有可能出現(xiàn)異常废登。憑 借經(jīng)驗(yàn)可判斷該在程序的什么地方包含異常處理塊,以及出現(xiàn)錯(cuò)誤時(shí)該向用戶提供多少相關(guān)的信息郁惜。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末堡距,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子扳炬,更是在濱河造成了極大的恐慌吏颖,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件恨樟,死亡現(xiàn)場(chǎng)離奇詭異半醉,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)劝术,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門缩多,熙熙樓的掌柜王于貴愁眉苦臉地迎上來呆奕,“玉大人,你說我怎么就攤上這事衬吆×杭兀” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵逊抡,是天一觀的道長姆泻。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任艰亮,我火速辦了婚禮,結(jié)果婚禮上方咆,老公的妹妹穿的比我還像新娘。我一直安慰自己蟀架,他們只是感情好瓣赂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著片拍,像睡著了一般煌集。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上穆碎,一...
    開封第一講書人閱讀 51,365評(píng)論 1 302
  • 那天牙勘,我揣著相機(jī)與錄音,去河邊找鬼所禀。 笑死方面,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的色徘。 我是一名探鬼主播恭金,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼褂策!你這毒婦竟也來了横腿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤斤寂,失蹤者是張志新(化名)和其女友劉穎耿焊,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體遍搞,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡罗侯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了溪猿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钩杰。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡纫塌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出讲弄,到底是詐尸還是另有隱情措左,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布避除,位于F島的核電站怎披,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏驹饺。R本人自食惡果不足惜钳枕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望赏壹。 院中可真熱鬧,春花似錦衔沼、人聲如沸蝌借。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽菩佑。三九已至,卻和暖如春凝化,著一層夾襖步出監(jiān)牢的瞬間稍坯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來泰國打工搓劫, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瞧哟,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓枪向,卻偏偏與公主長得像勤揩,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子秘蛔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

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

  • 一陨亡、簡介 Python最強(qiáng)大的結(jié)構(gòu)之一就是它的異常處理能力,所有的標(biāo)準(zhǔn)異常都使用類來實(shí)現(xiàn)深员,都是基類Exceptio...
    隨風(fēng)化作雨閱讀 3,073評(píng)論 0 1
  • python使用被稱為異常的特殊對(duì)象來管理程序執(zhí)行期間發(fā)生的錯(cuò)誤负蠕。每當(dāng)發(fā)生讓python不知所措的錯(cuò)誤時(shí),...
    路_堯知百戰(zhàn)勝閱讀 509評(píng)論 0 0
  • 一倦畅、錯(cuò)誤和異常 1遮糖、錯(cuò)誤 從軟件方面來講,錯(cuò)誤通常是語法或邏輯上的滔迈。語法錯(cuò)誤會(huì)導(dǎo)致程序代碼不能被解釋器解釋止吁,這些錯(cuò)...
    常大鵬閱讀 1,340評(píng)論 0 6
  • Python異常處理 異常概念: 異常:就是不正常的情況被辑,程序開發(fā)過程中錯(cuò)誤和BUG都是補(bǔ)充正常的情況 異常發(fā)生的...
    youngkun閱讀 924評(píng)論 0 4
  • React Native在0.43版本之前寫列表需要使用ListView,ListView存在性能問題敬惦,API也不...
    henry_g閱讀 3,506評(píng)論 2 2