Python基础教程【读书笔记】 - 2016/7/5
希望通過博客園持續(xù)的更新,分享和記錄Python基礎(chǔ)知識(shí)到高級(jí)應(yīng)用的點(diǎn)點(diǎn)滴滴!
第三波:第8章 ?異常
[總覽]學(xué)習(xí)如何創(chuàng)建和引發(fā)自定義的異常,以及處理異常的各種方法。
為了能夠處理異常事件,可以再所有可能發(fā)生這類事件的地方都使用條件語句,但是這么做可能不僅會(huì)沒效率和不靈活,而且還會(huì)讓程序難以閱讀。Python的異常對(duì)象提供了非常強(qiáng)大的替代解決方案。
[8.1] 什么是異常
Python用異常對(duì)象(exception object)來表示異常情況。遇到錯(cuò)誤后,會(huì)引發(fā)異常。如果異常對(duì)象并未被處理或捕捉,程序就會(huì)用所謂的回溯(Traceback,一種錯(cuò)誤信息)終止執(zhí)行。
事實(shí)上,每個(gè)異常都是一些類的實(shí)例,這些實(shí)例可以被引發(fā),并且可以用多種方法進(jìn)行捕捉,使得程序可以捉住錯(cuò)誤并且對(duì)其進(jìn)行處理,而不是讓整個(gè)程序失敗。
[8.2] 按自己的方式出錯(cuò)
異常可以在某些東西出錯(cuò)時(shí)自動(dòng)引發(fā)。先學(xué)習(xí)如何引發(fā)異常---甚至創(chuàng)建自己的異常類型。
[8.2.1] raise語句
為了引發(fā)異常,可以使用一個(gè)類(應(yīng)該是Exception的子類)或者實(shí)例參數(shù)調(diào)用raise語句。使用類時(shí)沒程序會(huì)自動(dòng)創(chuàng)建實(shí)例。如下使用內(nèi)建的Exception異常類:
raise Exception
raise Exception('Hyperdrive overload')
第一個(gè)例子raise Exception引發(fā)一個(gè)沒有任何有關(guān)錯(cuò)誤信息的普通異常,后一個(gè)例子中,則添加了一些hyperdive overload錯(cuò)誤信息。
內(nèi)建的異常類有很多,內(nèi)建異常都可以再exception模塊中找到。使用dir函數(shù)列出模塊的內(nèi)容:
import exception
dir(exception)
所有這些異常都可以用在raise語句中:
raise ArithmeticError
表8-1 一些內(nèi)建異常
類名 描述
Exception 所有異常的基類
AttributeError ?特性引用或賦值失敗時(shí)引發(fā)
IOError 試圖打開不存在文件時(shí)引發(fā)
IndexError 在使用序列中不存在的索引時(shí)引發(fā)
KeyError 在使用映射中不存在的鍵時(shí)引發(fā)
NameError 在找不到名字(變量)時(shí)引發(fā)
SyntaxError ?在代碼為錯(cuò)誤形式時(shí)引發(fā)
TypeError ?在內(nèi)建操作或者函數(shù)應(yīng)用于錯(cuò)誤類型的對(duì)象時(shí)引發(fā)
ValueError 在內(nèi)建操作或者函數(shù)應(yīng)用于正確類型的對(duì)象,但該對(duì)象使用不合適的值時(shí)引發(fā)?
ZeroDivisionError 在除法或者模除操作的第二個(gè)參數(shù)為0時(shí)引發(fā)
[8.2.2] 自定義異常類
有些時(shí)候創(chuàng)建自己的異常類。那么如何創(chuàng)建自己的異常類呢?只是要確保從Exception類繼承(不管是間接的或者是直接的,也就是說繼承其他的內(nèi)建異常類也是可以的),編寫一個(gè)自定義異常類基本上如下:
class SomeCustomException(Exception):pass
[8.3] 捕捉異常
關(guān)于異常最有意思的地方就是可以處理它們(通常叫做誘捕或者捕捉異常),可以使用try/except來實(shí)現(xiàn)。
為了捕捉異常并且做出一些錯(cuò)誤處理,如下:
try:
x=input('Enter the first number:')
y=input('Enter the second number:')
print x/y
except ZeroDivisionError:
print "The second number can't be zero!"
看起來用if語句檢查y值會(huì)更簡(jiǎn)單一些,但是如果需要給程序加入更多除法,那么就得給每個(gè)除法加個(gè)if語句。而使用try/except的話只需要一個(gè)錯(cuò)誤處理器。
如果捕捉到了有慈航,但是又想重新引發(fā)它(也就是說要傳遞異常),那么可以調(diào)用不帶參數(shù)的raise。
class MuffledCalculator:
muffled=False
def calc(self,expr):
try:
return eval(expr)
except ZeroDivisionError:
if self.muffled:
print 'Division by zero is illegal'
else:
raise
[8.4] 不止一個(gè)except子句
可以再同一個(gè)try/except語句后面加上另一個(gè)except子句。
try:
x=input('Enter the first number:')
y=input('Enter the second number:')
print x/y
except ZeroDivisionError:
print "The second number can't be zero!"
except TypeError:
print "That wan't a number ,was it?"
應(yīng)該注意到,異常處理并不會(huì)將搞亂原來的代碼,而增加一大堆if語句檢查可能的錯(cuò)誤情況會(huì)讓代碼相當(dāng)難度。
[8.5]?用一個(gè)塊捕捉兩個(gè)異常
? 如果需要用一個(gè)塊捕捉多個(gè)類型異常,那么可以將它們作為元組列出,像下面這樣:
try:
x=input('Enter the first number:')
y=input('Enter the second number:')
print x/y
except (ZeroDivisionError,TypeError,NameError):
print 'Your number were bogus...'
注意except子句中異常對(duì)象外面的圓括號(hào)很重要。忽略它們是一種常見的錯(cuò)誤。
[8.6] 捕捉對(duì)象
如果希望在except子句訪問異常對(duì)象本身,可以使用兩個(gè)參數(shù)。注意,就算捕捉到多個(gè)異常,也只需向except子句提供一個(gè)參數(shù)。如果想讓程序繼續(xù)運(yùn)行,但是又因?yàn)槟撤N原因想記錄下錯(cuò)誤,這個(gè)功能就很有用。
try:
x=input('Enter the first number:')
y=input('Enter the second number:')
print x/y
except (ZeroDivisionError,TypeError),e:
print e
[8.7] 真正的全捕捉
如果真的想用一段代碼捕捉所有異常,那么可以在except子句中忽略所有的異常類:
try:
......
except:
print 'Something wrong happened...'
這樣捕捉所有異常時(shí)危險(xiǎn)的,因?yàn)樗鼤?huì)隱藏所有程序員未想到并未做好準(zhǔn)備處理的錯(cuò)誤。
[8.8] 萬事大吉
可以像對(duì)條件和循環(huán)語句那樣,給try/except語句價(jià)格else子句:
try:
print 'A simple task'
except:
print 'What? Something went wrong!'
else:
print 'Ah...It went as planned!'
[8.9] 最后......
最后是finally子句,它可以用來在可能的異常后進(jìn)行清理,它和try子句聯(lián)合使用:
x=None
try:
x=1/0
finally:
print 'Cleaning up...'
del x
上面的代碼中,finally子句肯定會(huì)被執(zhí)行,不管try子句中是否發(fā)生異常。因?yàn)槭褂胐el語句刪除一個(gè)變量是非常不負(fù)責(zé)的清理手段,所以finally子句用于關(guān)閉文件或者網(wǎng)絡(luò)套接字時(shí)會(huì)非常有用。還可以在同一條語句中組合使用try、except、finally和else。
try:
1/0
except NameError:
print 'Unknown variable'
else:
print "That went well!"
finally:
print "Cleaning up....."
[8.10] 異常和函數(shù)
異常和函數(shù)能很自然地一起工作。如果異常在函數(shù)內(nèi)引發(fā)而不被處理,它就會(huì)傳播至函數(shù)調(diào)用的地方。如果在那里也沒有處理異常,它就會(huì)繼續(xù)傳播,一直到達(dá)主程序(全局作用域)。如果那里沒有異常處理程序,程序會(huì)帶著堆棧跟蹤中止。
[8.11] 異常之禪
異常處理并不是很復(fù)雜。如果知道某段代碼可能會(huì)導(dǎo)致某種異常,而又不希望程序以堆棧跟蹤的形式終止,那么久根據(jù)需要添加try/except或者try/finally語句進(jìn)行處理。
[8.12] 小結(jié)
異常對(duì)象:異常情況可以用異常對(duì)象表示。
警告:警告類似于異常,但是一般來說僅僅打印錯(cuò)誤信息。
引發(fā)異常:可以使用raise語句引發(fā)異常。它接受異常類或者異常實(shí)例作為參數(shù),還能提供兩個(gè)參數(shù)(異常和錯(cuò)誤信息)。
自定義異常類:用繼承Exception類的方法可以創(chuàng)建自己的異常類。
捕捉異常:使用try語句的except子句捕捉異常。異常可以放在元組中以實(shí)現(xiàn)多個(gè)異常的制定。如果給except提供兩個(gè)參數(shù),第2個(gè)參數(shù)就會(huì)綁定到異常對(duì)象上。同樣,在一個(gè)try/except語句中能包含多個(gè)except子句,用來分別處理不同的異常。
else子句:如果主try塊中沒有引發(fā)異常,else子句就會(huì)被執(zhí)行。
finally:如果需要確保某些代碼不管是否有異常引發(fā)都要執(zhí)行,那么這些代碼可以防止在finally子句中。
異常和函數(shù):在函數(shù)內(nèi)引發(fā)異常時(shí),它就會(huì)被傳播到函數(shù)調(diào)用的地方。
?
轉(zhuǎn)載于:https://www.cnblogs.com/pythonMLer/p/5642161.html
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的Python基础教程【读书笔记】 - 2016/7/5的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 切换debian8系统语言环境
- 下一篇: Python Model : glob