第八章 異常

2021-07-31 11:41:49 字數 4525 閱讀 6382

python用異常物件(exception object)表示異常情況。遇到錯誤後,會引發異常。如果異常物件未被處理或捕捉,程式就會用回溯(traceback,一種錯誤資訊)終止執行。每個異常都是一些類的例項

使用乙個類(exception的子類)或例項引數呼叫raise

捕捉異常並且進行處理,而不讓整個程式崩潰

>>> raise exception

traceback (most recent call last):

file "", line 1, in raise exception

exception

>>> raise exception("hyperdrive overload")#新增錯誤資訊

traceback (most recent call last):

file "", line 1, in raise exception("hyperdrive overload")#新增錯誤資訊

exception: hyperdrive overload

可以新增錯誤資訊

可以使用dir(exceptions)  列出內建異常 

表8-1描述了一些最重要的內建異常類:

表8-1 一些內建異常類

exception            所有異常的基類

attributeerror           特性引用或賦值失敗時引發

ioerror             試圖開啟不存在檔案(包括其他情況)時引發

indexerror                                         在使用序列中不存在的索引時引發

keyerror              在使用對映中不存在的鍵時引發

nameerror             在找不到名字(變數)時引發

syntaxerror            在**為錯誤形式時引發

typeerror             在內建操作或者函式應用於錯誤型別的物件時引發

valueerror            在內建操作或者函式應用於正確型別的物件,但是該物件使用不合適的值時引發

zerodivisionerror         在除法或者模除操作的第二個引數為0時引發

為什麼要自定義?

可以根據異常所在的類,選擇性地處理當前型別的異常。所以如果想要用特殊的錯誤處理**處理錯誤,就要自定義乙個異常類。

如何建立?

確保自定義類是從exception類繼承的(直接或者間接)

class somecustomexception(exception): pass

8.3    捕捉異常(處理異常)

重點   使用.  try....except

enter the first number: 10

enter the second number: 0

traceback (most recent call last):

file "/home/marlowes/mypython/my_exception.py", line 6, in print x / y

zerodivisionerror: integer division or modulo by zero

使用try.....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!"

讓錯誤發生時,執行別的語句

比if要好,因為只要寫乙個錯誤處理器.

注:如果沒有捕捉異常,它就會被「傳播」到呼叫的函式中。如果在那裡依然沒有捕獲,這些異常就會「浮」到程式的最頂層,也就是說你可以捕捉到在其他人的函式中所引發的異常。有關這方面的更多資訊,請參見8.10節。    8.10(看不懂,之後再來看

異常的丟擲機制:

1、如果在執行時發生異常,直譯器會查詢相應的處理語句(稱為handler).

2、要是在當前函式裡沒有找到的話,它會將異常傳遞給上層的呼叫函式,看看那裡能不能處理。

3、如果在最外層(全域性「main」

)還是沒有找到的話,程式會帶著棧跟蹤終止,同時列印出

traceback

以便讓使用者找到錯誤產生的原因。

>>> def faulty():

... raise exception("something is wrong")

...

>>> def ignore_exception():

... faulty()

...

>>> def handle_exception():

... try:

... faulty()

... except:

... print "exception handled"

...

>>> ignore_exception()

traceback (most recent call last):

file "", line 1, in file "", line 2, in ignore_exception

file "", line 2, in faulty

exception: something is wrong

>>> handle_exception()

exception handled

可以看到,faulty中產生的異常通過faulty->ingore_exception傳播,最終導致棧跟蹤,handle_exception同理

如果捕捉到了異常,但是又想重新引發它(也就是說要傳遞異常,不進行處理),那麼可以呼叫

不帶引數的raise

(還能在捕捉到異常時顯式地提供具體異常,在8.6節會對此進行解釋)。          重新把異常繼續向上傳遞。

作用:舉個例子吧,看看這麼做多麼有用:考慮一下乙個能「遮蔽」zerodivisionerror(除零錯誤)的計算器類。如果這個行為被啟用,那麼計算器就列印錯誤資訊,而不是讓異常傳播(說明沒except異常)。如果在與使用者互動的過程中使用,那麼這就有用了,但是如果是在程式內部使用,引發異常會更好些。因此「遮蔽」機制就可以關掉了,下面是這樣乙個類的**:

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 #關閉遮蔽

注:如果除零行為發生而遮蔽機制被開啟,那麼calc方法會(隱式地)

返回none

。換句話說,如果開啟了遮蔽機制,那麼就不應該依賴返回值。

8.4 使用多個except

1.使用多個子句

2.使用元組包含多個異常型別

8.6 捕捉物件

在except子句中訪問異常物件本身

顯示的捕捉物件本身

下面的示例程式會列印異常(如果發生的話),但是程式會繼續執行:

try:

x = input("enter the first number: ")

y = input("enter the second number: ")

print x / y

except (zerodivisionerror, typeerror), e:#as e 在python3.0中

print e

8.7 全捕捉

直接使用 except:    (不加入錯誤型別),捕捉所有異常 危險

可以使用 except exception,e:      會更好,這樣可以對e做一些檢查

8.8 else

沒出現錯誤時,執行else

8.9 finally

不管異常是否發生,都執行

通常用來清理

x = none

try:

x = 1 / 0

finally:

print "cleaning up..."

del x

在程式traceback之前,清理就已經完成。

第八章 指標 第八章 指標

1 什麼是位址 include using namespace std int main 11 在堆中建立對像 我們既然可以在堆中儲存變數,那麼也就可以儲存對像,我們可以將對像儲存堆中,然後通過指標來訪問它 include using namespace std class human 14 在建構...

python第八章測試題答案 第八章 異常處理

toc 異常處理 python所有的錯誤都是從baseexception類派生的,常見的錯誤型別和繼承關係看這裡 語法 python try pass except pass finally pass 例 try print 10 0 except exception,e print e final...

第八章(筆記)

能在 中進行記憶體單元的定址的暫存器只有4個,分別是bx si di bp 其中bx bp 是基址,bx對應的段位址是ds,bp對應的段位址是ss si di 是變址,單獨使用時段位址是ds,組合使用段位址是跟隨組合的基址對應的段位址 中進行記憶體單元定址彙總 si di bx bp 常量 si 常...