天天看點

異常處理

一、概念

異常就是程式運作時發生錯誤的信号(在程式出現錯誤時,則會産生一個異常,若程式沒有處理它,則會抛出該異常,程式的運作也随之終止

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>'&gt;&gt;: '</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) &gt; </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,如需轉載請自行聯系原作者