try...except...是處理異常的基本方式。在原來的基礎上,還可有擴展。
## [](https://github.com/qiwsir/StarterLearningPython/blob/master/217.md#處理多個異常)處理多個異常
處理多個異常,并不是因為同時報出多個異常。程序在運行中,只要遇到一個異常就會有反應,所以,每次捕獲到的異常一定是一個。所謂處理多個異常的意思是可以容許捕獲不同的異常,有不同的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
~~~
將上節的一個程序進行修改,增加了一個except子句,目的是如果用戶輸入的不是數字時,捕獲并處理這個異常。測試如下:
~~~
$ python 21701.py
this is a division program.
input 'c' continue, otherwise logout:c
first number:3
second number:"hello" #輸入了一個不是數字的東西
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里面如果有一個異常,就轉到相應的except子句,其它的忽略。如果except沒有相應的異常,該異常也會拋出,不過這是程序就要中止了,因為異常“浮出”程序頂部。
除了用多個except之外,還可以在一個except后面放多個異常參數,比如上面的程序,可以將except部分修改為:
~~~
except (ZeroDivisionError, ValueError):
print "please input rightly."
print "********************"
~~~
運行的結果就是:
~~~
$ 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后面如果是多個參數,一定要用圓括號包裹起來。否則,后果自負。
突然有一種想法,在對異常的處理中,前面都是自己寫一個提示語,發現自己寫的不如內置的異常錯誤提示更好。希望把它打印出來。但是程序還能不能中斷。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
~~~
運行一下,看看提示信息。
~~~
$ 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`,后面什么參數也不寫就好了。
## [](https://github.com/qiwsir/StarterLearningPython/blob/master/217.md#else子句)else子句
有了`try...except...`,在一般情況下是夠用的,但總有不一般的時候出現,所以,就增加了一個else子句。其實,人類的自然語言何嘗不是如此呢?總要根據需要添加不少東西。
~~~
>>> try:
... print "I am try"
... except:
... print "I am except"
... else:
... print "I am else"
...
I am try
I am else
~~~
這段演示,能夠幫助讀者理解else的執行特點。如果執行了try,則except被忽略,但是else被執行。
~~~
>>> try:
... print 1/0
... except:
... print "I am except"
... else:
... print "I am else"
...
I am except
~~~
這時候else就不被執行了。
理解了else的執行特點,可以寫這樣一段程序,還是類似于前面的計算,只不過這次要求,如果輸入的有誤,就不斷要求從新輸入,知道輸入正確,并得到了結果,才不再要求輸入內容,程序結束。
在看下面的參考代碼之前,讀者是否可以先自己寫一段呢?并調試一下,看看結果如何。
~~~
#!/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
~~~
先看運行結果:
~~~
$ python 21703.py
the first number:2
the second number:0 #異常,執行except
float division by zero
try again. #循環
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 #正常,執行try
2.0 #然后else:break,退出程序
$
~~~
相當滿意的執行結果。
需要對程序中的except簡單說明,這次沒有像前面那樣寫,而是`except Exception, e`,意思是不管什么異常,這里都會捕獲,并且傳給變量e,然后用`print e`把異常信息打印出來。
## [](https://github.com/qiwsir/StarterLearningPython/blob/master/217.md#finally)finally
finally子句,一聽這個名字,就感覺它是做善后工作的。的確如此,如果有了finally,不管前面執行的是try,還是except,它都要執行。因此一種說法是用finally用來在可能的異常后進行清理。比如:
~~~
>>> 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
~~~
當然,在應用中,可以將上面的各個子句都綜合起來使用,寫成如下樣式:
~~~
try:
do something
except:
do something
else:
do something
finally
do something
~~~
## [](https://github.com/qiwsir/StarterLearningPython/blob/master/217.md#和條件語句相比)和條件語句相比
`try...except...`在某些情況下能夠替代`if...else..`的條件語句。這里我無意去比較兩者的性能,因為看到有人討論這個問題。我個人覺得這不是主要的,因為它們之間性能的差異不大。主要是你的選擇。一切要根據實際情況而定,不是說用一個就能包打天下。
- 第零章 預備
- 關于Python的故事
- 從小工到專家
- Python安裝
- 集成開發環境
- 第壹章 基本數據類型
- 數和四則運算
- 除法
- 常用數學函數和運算優先級
- 寫一個簡單的程序
- 字符串(1)
- 字符串(2)
- 字符串(3)
- 字符串(4)
- 字符編碼
- 列表(1)
- 列表(2)
- 列表(3)
- 回顧list和str
- 元組
- 字典(1)
- 字典(2)
- 集合(1)
- 集合(2)
- 第貳章 語句和文件
- 運算符
- 語句(1)
- 語句(2)
- 語句(3)
- 語句(4)
- 語句(5)
- 文件(1)
- 文件(2)
- 迭代
- 練習
- 自省
- 第叁章 函數
- 函數(1)
- 函數(2)
- 函數(3)
- 函數(4)
- 函數練習
- 第肆章 類
- 類(1)
- 類(2)
- 類(3)
- 類(4)
- 類(5)
- 多態和封裝
- 特殊方法(1)
- 特殊方法(2)
- 迭代器
- 生成器
- 上下文管理器
- 第伍章 錯誤和異常
- 錯誤和異常(1)
- 錯誤和異常(2)
- 錯誤和異常(3)
- 第陸章 模塊
- 編寫模塊
- 標準庫(1)
- 標準庫(2)
- 標準庫(3)
- 標準庫(4)
- 標準庫(5)
- 標準庫(6)
- 標準庫(7)
- 標準庫(8)
- 第三方庫
- 第柒章 保存數據
- 將數據存入文件
- mysql數據庫(1)
- MySQL數據庫(2)
- mongodb數據庫(1)
- SQLite數據庫
- 電子表格
- 第捌章 用Tornado做網站
- 為做網站而準備
- 分析Hello
- 用tornado做網站(1)
- 用tornado做網站(2)
- 用tornado做網站(3)
- 用tornado做網站(4)
- 用tornado做網站(5)
- 用tornado做網站(6)
- 用tornado做網站(7)
- 第玖章 科學計算
- 為計算做準備
- Pandas使用(1)
- Pandas使用(2)
- 處理股票數據
- 附:網絡文摘
- 如何成為Python高手
- ASCII、Unicode、GBK和UTF-8字符編碼的區別聯系