鍍金池/ 教程/ Python/ 錯誤和異常 (2)
標(biāo)準(zhǔn)庫 (4)
如何成為 Python 高手
標(biāo)準(zhǔn)庫 (6)
標(biāo)準(zhǔn)庫 (3)
類(2)
Pandas 使用 (2)
xml
用 tornado 做網(wǎng)站 (5)
文件(1)
練習(xí)
列表(3)
從小工到專家
除法
錯誤和異常 (2)
函數(shù)(1)
用 tornado 做網(wǎng)站 (7)
為做網(wǎng)站而準(zhǔn)備
函數(shù)練習(xí)
標(biāo)準(zhǔn)庫 (8)
Pandas 使用 (1)
回顧 list 和 str
字典(1)
用 tornado 做網(wǎng)站 (3)
字符串(1)
函數(shù)(2)
寫一個簡單的程序
將數(shù)據(jù)存入文件
語句(5)
SQLite 數(shù)據(jù)庫
集成開發(fā)環(huán)境(IDE)
集合(1)
類(1)
用 tornado 做網(wǎng)站 (6)
用 tornado 做網(wǎng)站 (2)
自省
語句(4)
錯誤和異常 (1)
用 tornado 做網(wǎng)站 (4)
集合(2)
列表(1)
標(biāo)準(zhǔn)庫 (1)
生成器
mysql 數(shù)據(jù)庫 (1)
第三方庫
實(shí)戰(zhàn)
運(yùn)算符
類(3)
字典(2)
語句(1)
數(shù)和四則運(yùn)算
語句(2)
文件(2)
MySQL 數(shù)據(jù)庫 (2)
電子表格
迭代器
mongodb 數(shù)據(jù)庫 (1)
特殊方法 (2)
特殊方法 (1)
字符編碼
編寫模塊
用 tornado 做網(wǎng)站 (1)
標(biāo)準(zhǔn)庫 (5)
函數(shù)(4)
類(5)
字符串(2)
關(guān)于 Python 的故事
函數(shù)(3)
字符串(4)
處理股票數(shù)據(jù)
常用數(shù)學(xué)函數(shù)和運(yùn)算優(yōu)先級
字符串(3)
為計算做準(zhǔn)備
多態(tài)和封裝
類(4)
迭代
語句(3)
錯誤和異常 (3)
分析 Hello
Python 安裝
標(biāo)準(zhǔn)庫 (2)
列表(2)
元組

錯誤和異常 (2)

try...except...是處理異常的基本方式。在原來的基礎(chǔ)上,還可有擴(kuò)展。

處理多個異常

處理多個異常,并不是因?yàn)橥瑫r報出多個異常。程序在運(yùn)行中,只要遇到一個異常就會有反應(yīng),所以,每次捕獲到的異常一定是一個。所謂處理多個異常的意思是可以容許捕獲不同的異常,有不同的 except 子句處理。

#!/usr/bin/env Python
# coding=utf-8

while 1:
    print "this is a division program."
    c = raw_input("input 'c' continue, otherwise logout:")
    if c == 'c':
        a = raw_input("first number:")
        b = raw_input("second number:")
        try:
            print float(a)/float(b)
            print "*************************"
        except ZeroDivisionError:
            print "The second number can't be zero!"
            print "*************************"
        except ValueError:
            print "please input number."
            print "************************"
    else:
        break

將上節(jié)的一個程序進(jìn)行修改,增加了一個 except 子句,目的是如果用戶輸入的不是數(shù)字時,捕獲并處理這個異常。測試如下:

$ python 21701.py 
this is a division program.
input 'c' continue, otherwise logout:c
first number:3
second number:"hello"        #輸入了一個不是數(shù)字的東西
please input number.         #對照上面的程序,捕獲并處理了這個異常
************************
this is a division program.
input 'c' continue, otherwise logout:c
first number:4
second number:0
The second number can't be zero!
*************************
this is a division program.
input 'c' continue, otherwise logout:4
$

如果有多個 except,在 try 里面如果有一個異常,就轉(zhuǎn)到相應(yīng)的 except 子句,其它的忽略。如果 except 沒有相應(yīng)的異常,該異常也會拋出,不過這是程序就要中止了,因?yàn)楫惓!案〕觥背绦蝽敳俊?/p>

除了用多個 except 之外,還可以在一個 except 后面放多個異常參數(shù),比如上面的程序,可以將 except 部分修改為:

except (ZeroDivisionError, ValueError):
    print "please input rightly."
    print "********************"

運(yùn)行的結(jié)果就是:

$ python 21701.py 
this is a division program.
input 'c' continue, otherwise logout:c
first number:2
second number:0           #捕獲異常
please input rightly.
********************
this is a division program.
input 'c' continue, otherwise logout:c
first number:3
second number:a           #異常
please input rightly.
********************
this is a division program.
input 'c' continue, otherwise logout:d
$

需要注意的是,except 后面如果是多個參數(shù),一定要用圓括號包裹起來。否則,后果自負(fù)。

突然有一種想法,在對異常的處理中,前面都是自己寫一個提示語,發(fā)現(xiàn)自己寫的不如內(nèi)置的異常錯誤提示更好。希望把它打印出來。但是程序還能不能中斷。Python 提供了一種方式,將上面代碼修改如下:

while 1:
    print "this is a division program."
    c = raw_input("input 'c' continue, otherwise logout:")
    if c == 'c':
        a = raw_input("first number:")
        b = raw_input("second number:")
        try:
            print float(a)/float(b)
            print "*************************"
        except (ZeroDivisionError, ValueError), e:
            print e
            print "********************"
    else:
        break

運(yùn)行一下,看看提示信息。

$ python 21702.py 
this is a division program.
input 'c' continue, otherwise logout:c
first number:2
second number:a                         #異常
could not convert string to float: a
********************
this is a division program.
input 'c' continue, otherwise logout:c
first number:2
second number:0                         #異常
float division by zero
********************
this is a division program.
input 'c' continue, otherwise logout:d
$

在 Python3.x 中,常常這樣寫:except (ZeroDivisionError, ValueError) as e:

以上程序中,之處理了兩個異常,還可能有更多的異常呢?如果要處理,怎么辦?可以這樣:execpt: 或者 except Exception, e,后面什么參數(shù)也不寫就好了。

else 子句

有了 try...except...,在一般情況下是夠用的,但總有不一般的時候出現(xiàn),所以,就增加了一個 else 子句。其實(shí),人類的自然語言何嘗不是如此呢?總要根據(jù)需要添加不少東西。

>>> try:
...     print "I am try"
... except:
...     print "I am except"
... else:
...     print "I am else"
... 
I am try
I am else

這段演示,能夠幫助讀者理解 else 的執(zhí)行特點(diǎn)。如果執(zhí)行了 try,則 except 被忽略,但是 else 被執(zhí)行。

>>> try:
...     print 1/0
... except:
...     print "I am except"
... else:
...     print "I am else"
... 
I am except

這時候 else 就不被執(zhí)行了。

理解了 else 的執(zhí)行特點(diǎn),可以寫這樣一段程序,還是類似于前面的計算,只不過這次要求,如果輸入的有誤,就不斷要求從新輸入,知道輸入正確,并得到了結(jié)果,才不再要求輸入內(nèi)容,程序結(jié)束。

在看下面的參考代碼之前,讀者是否可以先自己寫一段呢?并調(diào)試一下,看看結(jié)果如何。

#!/usr/bin/env Python
# coding=utf-8
while 1:
    try:
        x = raw_input("the first number:")
        y = raw_input("the second number:")

        r = float(x)/float(y)
        print r
    except Exception, e:
        print e
        print "try again."
    else:
        break

先看運(yùn)行結(jié)果:

$ python 21703.py
the first number:2
the second number:0        #異常,執(zhí)行 except
float division by zero
try again.                 #循環(huán)
the first number:2
the second number:a        #異常 
could not convert string to float: a
try again.
the first number:4
the second number:2        #正常,執(zhí)行 try
2.0                        #然后 else:break,退出程序
$

相當(dāng)滿意的執(zhí)行結(jié)果。

需要對程序中的 except 簡單說明,這次沒有像前面那樣寫,而是 except Exception, e,意思是不管什么異常,這里都會捕獲,并且傳給變量 e,然后用 print e 把異常信息打印出來。

finally

finally 子句,一聽這個名字,就感覺它是做善后工作的。的確如此,如果有了 finally,不管前面執(zhí)行的是 try,還是 except,它都要執(zhí)行。因此一種說法是用 finally 用來在可能的異常后進(jìn)行清理。比如:

>>> x = 10

>>> try:
...     x = 1/0
... except Exception, e:
...     print e
... finally:
...     print "del x"
...     del x
... 
integer division or modulo by zero
del x

看一看 x 是否被刪除?

>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined

當(dāng)然,在應(yīng)用中,可以將上面的各個子句都綜合起來使用,寫成如下樣式:

try:
    do something
except:
    do something
else:
    do something
finally
    do something

和條件語句相比

try...except...在某些情況下能夠替代 if...else.. 的條件語句。這里我無意去比較兩者的性能,因?yàn)榭吹接腥擞懻撨@個問題。我個人覺得這不是主要的,因?yàn)樗鼈冎g性能的差異不大。主要是你的選擇。一切要根據(jù)實(shí)際情況而定,不是說用一個就能包打天下。


總目錄   |   上節(jié):錯誤和異常(1)   |   下節(jié):錯誤和異常(3)

如果你認(rèn)為有必要打賞我,請通過支付寶:qiwsir@126.com,不勝感激。