python異常處理

1. 異常

(1) 異常處理

#沒有異常處理
num = int('abc')
print(num)          #報錯


#異常處理
try:
    num = int('abc')      #try裏的代碼是受保護的
    print(num)
except Exception as e:
    print(e)            #輸出invalid literal for int() with base 10: 'abc',程序正常運行

e是由Exception類實例化的一個對象html

class Exception(BaseException):
    """ Common base class for all non-exit exceptions. """
    def __init__(self, *args, **kwargs): # real signature unknown
        pass

    @staticmethod # known case of __new__
    def __new__(*args, **kwargs): # real signature unknown
        """ Create and return a new object.  See help(type) for accurate signature. """
        pass

(2) 異常分類

Exception是萬能的異常捕捉方法,能夠捕捉到任何錯誤。python

li = []
inp = input('請輸入內容:')
try:
    li = []
    li[999]

except IndexError as e:  # 特殊異常須要優先匹配
    print('索引錯誤')
except Exception as e:
    print(e)
常見異常
AttributeError 試圖訪問一個對象沒有的樹形,好比foo.x,可是foo沒有屬性x
IOError 輸入/輸出異常;基本上是沒法打開文件
ImportError 沒法引入模塊或包;基本上是路徑問題或名稱錯誤
IndentationError 語法錯誤(的子類) ;代碼沒有正確對齊
IndexError 下標索引超出序列邊界,好比當x只有三個元素,卻試圖訪問x[5]
KeyError 試圖訪問字典裏不存在的鍵
KeyboardInterrupt Ctrl+C被按下
NameError 使用一個還未被賦予對象的變量
SyntaxError Python代碼非法,代碼不能編譯(我的認爲這是語法錯誤,寫錯了)
TypeError 傳入對象類型與要求的不符合
UnboundLocalError 試圖訪問一個還未被設置的局部變量,基本上是因爲另有一個同名的全局變量,致使你覺得正在訪問它
ValueError 傳入一個調用者不指望的值,即便值的類型是正確的

Python的錯誤其實也是class,全部的錯誤類型都繼承自BaseException,因此在使用except時須要注意的是,它不但捕獲該類型的錯誤,還把其子類也「一網打盡」。好比:函數

try:
    foo()
except ValueError as e:
    print('ValueError')
except UnicodeError as e:
    print('UnicodeError')

第二個except永遠也捕獲不到UnicodeError,由於UnicodeError是ValueError的子類,若是有,也被第一個except給捕獲了。code

Python全部的錯誤都是從BaseException類派生的,常見的錯誤類型和繼承關係看這裏:
https://docs.python.org/3/library/exceptions.html#exception-hierarchyhtm

使用try...except捕獲錯誤還有一個巨大的好處,就是能夠跨越多層調用,好比函數main()調用foo(),foo()調用bar(),結果bar()出錯了,這時,只要main()捕獲到了,就能夠處理:對象

def foo(s):
    return 10 / int(s)

def bar(s):
    return foo(s) * 2

def main():
    try:
        bar('0')
    except Exception as e:
        print('Error:', e)
    finally:
        print('finally...')

也就是說,不須要在每一個可能出錯的地方去捕獲錯誤,只要在合適的層次去捕獲錯誤就能夠了。這樣一來,就大大減小了寫try...except...finally的麻煩。繼承

(3) 異常實例

#IndexError
dic = ["wupeiqi", 'alex']
try:
    dic[10]
except IndexError, e:
    print e

#KeyError
dic = {'k1':'v1'}
try:
    dic['k20']
except KeyError, e:
    print e
    
#ValueError
s1 = 'hello'
try:
    int(s1)
except ValueError, e:
    print e

(4) 異常的結構

完整的基本結構以下索引

try:
    # 主代碼塊
    pass
except KeyError as e:
    # 異常時,執行該塊
    pass
else:
    # 主代碼塊執行完,執行該塊
    pass
finally:
    # 不管異常與否,最終執行該塊
    pass

(5) 主動觸發異常

try:
    raise Exception('錯誤了。。。')
except Exception as e:
    print e

(6) 自定義異常

class WupeiqiException(Exception):
 
    def __init__(self, msg):
        self.message = msg
 
    def __str__(self):
        return self.message
 
try:
    raise WupeiqiException('個人異常')
except WupeiqiException,e:
    print e

(7) 斷言

# assert 條件
assert 1 == 1   #條件成立程序正常運行
assert 1 == 2   #不成裏就會報錯,程序就異常
相關文章
相關標籤/搜索