一、概念
異常就是程式運作時發生錯誤的信号(在程式出現錯誤時,則會産生一個異常,若程式沒有處理它,則會抛出該異常,程式的運作也随之終止
1、錯誤包括文法錯誤和邏輯錯誤
(1)文法錯誤
這種錯誤python解釋器檢測錯誤時不能通過,必須在程式執行前就改正錯誤
class Foo #文法錯誤 SyntaxError: invalid syntax
pass
(2)邏輯錯誤
1
2
3
4
<code>l</code><code>=</code><code>[</code><code>'egon'</code><code>,</code><code>'aa'</code><code>]</code>
<code>l[</code><code>3</code><code>] </code><code>#報錯IndexError</code>
<code>dic</code><code>=</code><code>{</code><code>'name'</code><code>:</code><code>'egon'</code><code>}</code>
<code>dic[</code><code>'age'</code><code>] </code><code>#報錯KeyError</code>
二、異常的種類
AttributeError #試圖通路一個對象沒有的樹形,比如foo.x,但是foo沒有屬性x
IOError #輸入/輸出異常;基本上是無法打開檔案
ImportError #無法引入子產品或包;基本上是路徑問題或名稱錯誤
IndentationError #文法錯誤(的子類) ;代碼沒有正确對齊
IndexError #下标索引超出序列邊界,比如通路不存在元素的下标
KeyError #試圖通路字典裡不存在的鍵
KeyboardInterrupt #Ctrl+C被按下
NameError #使用一個還未被賦予對象的變量
SyntaxError #Python代碼非法,代碼不能編譯(個人認為這是文法錯誤,寫錯了)
TypeError #傳入對象類型與要求的不符合
UnboundLocalError #試圖通路一個還未被設定的局部變量,基本上是由于另有一個同名的全局變量,導緻你以為正在通路它
ValueError #傳入一個調用者不期望的值,即使值的類型是正确的
三、異常處理
為了保證程式的健壯性與容錯性,即在遇到錯誤時程式不會崩潰,我們需要對異常進行處理
1、如果錯誤發生的條件是可預知的,需要用if進行處理
5
6
7
8
<code>AGE</code><code>=</code><code>22</code>
<code>while</code> <code>True</code><code>:</code>
<code> </code><code>age</code><code>=</code><code>input</code><code>(</code><code>'>>: '</code><code>).strip()</code>
<code> </code><code>if</code> <code>age.isdigit(): </code><code>#隻有在age為字元串形式的整數時,下列代碼才不會出錯,如果不是報錯IndentationError: unindent does not match any outer indentation level</code>
<code> </code><code>age</code><code>=</code><code>int</code><code>(age)</code>
<code> </code><code>if</code> <code>age </code><code>=</code><code>=</code> <code>AGE:</code>
<code> </code><code>print</code><code>(</code><code>'you got it'</code><code>)</code>
<code> </code><code>break</code>
2、如果錯誤發生的條件是不可預知的,則需要用到try...except進行處理
(1)多分支異常處理,判斷屬于哪一種異常類型
9
<code>s1 </code><code>=</code> <code>'hello'</code>
<code>try</code><code>:</code>
<code> </code><code>int</code><code>(s1)</code>
<code>except</code> <code>IndexError as e:</code>
<code> </code><code>print</code><code>(e)</code>
<code>except</code> <code>KeyError as e:</code>
<code>except</code> <code>ValueError as e:</code>
(2)萬能異常Exception,可以比對到所有的異常
<code>except</code> <code>Exception as e:</code>
<code>如果你想要的效果是,無論出現什麼異常,我們統一丢棄,或者使用同一段代碼邏輯去處理他們,那麼隻有一個Exception就足夠了。</code>
<code>如果你想要的效果是,對于不同的異常我們需要定制不同的處理邏輯,那就需要用到多分支了。</code>
(3)異常的其他機構
10
11
12
13
<code>else</code><code>:</code>
<code> </code><code>print</code><code>(</code><code>'try内代碼塊沒有異常則執行我'</code><code>)</code>
<code>finally</code><code>:</code>
<code> </code><code>print</code><code>(</code><code>'無論異常與否,都會執行該子產品,通常是進行清理工作'</code><code>)</code>
(4)主動觸發異常
<code> </code><code>raise</code> <code>TypeError(</code><code>'類型錯誤'</code><code>)</code>
<code>當程式下部分用到上部分的結果時,可以判斷上面的結果是否滿足下部分所需要的條件,比如上面得到ip位址,下面驗證可用性,可以在中間判斷ip位址清單是否為空</code>
<code>ip_list</code><code>=</code><code>[</code>
<code> </code><code># '1.1.1.1:8080',</code>
<code> </code><code># '1.1.1.2:8081',</code>
<code> </code><code># '1.1.1.3:8082',</code>
<code>]</code>
<code>if</code> <code>len</code><code>(ip_list) </code><code>=</code><code>=</code> <code>0</code><code>:</code>
<code> </code><code>raise</code> <code>TypeError</code>
(5)斷言:assert 條件
<code>上面的使用</code><code>if</code><code>條件實作主動觸發異常,這裡使用斷言就可以實作相同的結果</code>
<code>assert</code> <code>len</code><code>(ip_list) > </code><code>0</code> <code>#當清單不為空時,正常執行下面的代碼,否則報異常</code>
(6)自定義異常
<code>class</code> <code>EgonException(BaseException):</code>
<code> </code><code>def</code> <code>__init__(</code><code>self</code><code>,msg):</code>
<code> </code><code>self</code><code>.msg</code><code>=</code><code>msg</code>
<code> </code><code>def</code> <code>__str__(</code><code>self</code><code>):</code>
<code> </code><code>return</code> <code>self</code><code>.msg</code>
<code> </code><code>raise</code> <code>EgonException(</code><code>'類型錯誤'</code><code>)</code>
<code>except</code> <code>EgonException as e:</code>
(7)總結try..except
1:把錯誤處理和真正的工作分開來
2:代碼更易組織,更清晰,複雜的工作任務更容易實作;
3:毫無疑問,程式更安全了,不至于由于一些小的疏忽而使程式意外崩潰了
四、異常處理的應用場景
首先try...except是你附加給程式的一種異常處理的邏輯,與主要的工作是沒有關系的,其次這種東西加的多了,會導緻程式代碼可讀性變差
是以隻有在錯誤發生的條件無法預知的情況下,才應該加上try...except處理異常
本文轉自 宋鵬超 51CTO部落格,原文連結:http://blog.51cto.com/qidian510/2066646,如需轉載請自行聯系原作者