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類實例化的一個對象

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是萬能的異常捕捉方法,可以捕捉到任何錯誤。

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給捕獲了。

Python所有的錯誤都是從BaseException類派生的,常見的錯誤類型和繼承關系看這里:
https://docs.python.org/3/library/exceptions.html#exception-hierarchy

使用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   #不成里就會報錯,程序就異常


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM