Python全棧之路系列----之-----異常處理

Python全棧之路系列之異常處理

初識異常處理

以下面的例子:python

讓用戶進行輸入,提示用戶輸入一個數字,若是輸入的事一個數字那個就把輸入的數字轉換爲int類型,而後輸出用戶輸入的而數字,若是用戶輸入的不是一個數字,那麼類型轉換就會出錯,若是出錯,就提示用戶」輸入類型錯誤,你因該輸入的是一個數字。」程序員

基礎語法:安全

try: 被檢測的代碼塊 except 異常類型: try中一旦檢測到異常,就執行這個位置的邏輯

 

  第一個例子:  asapp

  # 關於一些異常的提示問題 你明確知道會發什麼什麼錯 就不用as
  # 在咱們不能徹底明確的知道這個錯誤究竟是發生了什麼的時候
  # 就用as 變量名,將變量中存儲的錯誤信息打印出來
  # 可是不知道報什麼錯誤的時候 就用as 把系統報的錯打印出來
函數

try: n = int(input("請輸出一個數字>>> ")) print("你輸入的數字是",n) # e是Exception的對象,Exception是一個類
except Exception as e: print("輸入類型錯誤,你因該輸入的是一個數字。") 請輸出一個數字>>> 123 你輸入的數字是 123 請輸出一個數字>>> abc 輸入類型錯誤,你因該輸入的是一個數字。

 

如何查看和找到報錯的異常

  python解釋器檢測到錯誤,觸發異常(也容許程序員本身觸發異常)spa

   找到報錯的是最後一行
  # 排錯的時候真正報錯的是最下面
  # 從下往上找最後一行 那個報錯的地方
  # python的自帶代碼是不會出錯的
code

  # 一個地方報錯 其餘地方不能用 程序不往下執行對象

       #異常觸發後且沒被處理的狀況下,程序就在當前異常處終止,後面的代碼不會運行,誰會去用一個運行着忽然就崩潰的軟件。
  # SyntaxError 語法錯誤 寫代碼執行前 就要處理完畢
blog

異常處理的應用

# 異常處理的應用 1,能夠用if規避 可是成本過高 各類判斷
# 2,有些報錯 不能用 if 處理了 StopIteration
# 異常處理的特色: 一旦發生異常,程序就不在執行
#放在try:中的代碼若是遇到except中的錯誤類型,就會自行except中的代碼
# 且一旦發生異常,try中的代碼就會停在異常處
# 不影響try語句以外的代碼執行
# except 監控一種錯誤類型只能處理對應的一種錯誤,其餘錯誤仍是會報錯
 

第二個例子:繼承

try:#一用就是一組 不能分開用
    num=input('num: ') int(num) print(num)# 一旦發生異常 就打印這句話

except ValueError: #觸發這個異常就提示 若是沒問題 就不執行
    print('輸入一個數字') print('aaaa')

 

多分支異常處理

  能夠寫好多except 去監控各類異常的報錯

  第三個例子

 

# try:
#     num = input('num : ')
#     int(num)  # ValueError
#     print(num)
#     a
#     sum(1, 2, 3)
# except ValueError:
#     print('請輸入一個數字')
# except NameError as nameerror:
#     print('產生了一個%s'%nameerror)
# except TypeError:
#     print('又一個錯誤誕生了')


多分支+Exception萬能異常處理


s1 = 'hello'
try:
    int(s1)
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
except ValueError as e:
    print(e)
except Exception as e:
    print(e)

萬能異常

  萬能異常報錯處理 找到第一個能處理異常的 就不會走下面的異常處理
  因此萬能異常 通常都放在全部異常處理的最後面

  #對於你已經能夠預見的可是不能徹底規避的必需要處理的異常,
  # 你應該去指定他的處理方式
  #對於其餘你不能預料的,在使用萬能異常處理

 

# try:
#     num = input('num : ')
#     int(num)  # ValueError
#     # b          #NameError
#     # sum(1,2,3)  #TypeError
#     # dic = {}
#     # dic['key']  #KeyError
#     l = []
#     l[1000]   #IndexError
#     l = [1,23]
#     l_iterator = iter(l)
#     next(l_iterator)
#     next(l_iterator)
#     next(l_iterator)  #StopIteration
# except ValueError:  #遇到能處理的 就不執行下面的萬能異常處理
#     print('請輸入一個數字')
# except Exception as e:    萬能異常處理  並打印異常的信息
#     print(e)

異常的其餘機構

  其餘機構包括 1.異常處理中的else語句 2.裝飾器中的異常處理

  3.finally 始終會執行的語句 4.assert(斷言) 5.主動觸發異常 和 自定義異常

 

1.異常處理中的else語句

# try:
#     a =1
# except NameError as e:
#     print(e)
# else:
#     print('當try語句中不會發生異常的時候執行else中的代碼啦')

 2.裝飾器中的異常處理

# def wrapper(func):
#     def inner(*args,**kwargs):
#         try:
#             return func(*args,**kwargs)
#         finally:
#             "被裝飾的函數執行以後要執行的內容"
#     return inner

 3.finally 這個關鍵字下的內容是 始終會執行的語句 不論是否有return

 

#finally
# def func():
#     try:
#         f = open('file')
#         int(f.read())
#     except ValueError as e:
#         a = 123
#         return a
#     finally:       #清理的工做 把以前的打開的連接 文件 都關掉
#                    #避免由於程序異常形成的浪費資源和邏輯問題
#         f.close()
#
# print(func())

4.assert  斷言

若是條件成立則成立,若是條件不成立則報錯。

assert 1 == 1  不報錯 而且執行下面的代碼
assert 1 == 2  直接報錯 而且繞不過這個錯誤,不執行下面的任何代碼

5.主動觸發異常 和 自定義異常

  若是須要捕獲和處理一個異常,又不但願異常在程序中死掉,通常都會利用raise傳遞異常

  用戶自定義的異常經過類編寫,且一般須要繼承Exception內置的異常類,基於類的異常容許腳本創建異常類型、繼承行爲以及附加狀態信息。

主動觸發異常 try:    # raise表示主動出發異常,而後建立一個Exception對象,Exception括號內的值就是Exception對象的值
    raise TypeError('類型錯誤'"主動出發的異常") except Exception as e:     # 輸出Exception對象的值
    print(e) 自定義異常 class EvaException(BaseException): def __init__(self,msg): self.msg=msg def __str__(self): return self.msg try: raise EvaException('類型錯誤') except EvaException as e: print(e) 自定義異常 >>> class Bar(Exception): ... pass ... >>> 
>>> def doomed(): ... raise Bar() ... >>> 
>>> try: ... doomed() ... except Bar as e: ... print('error') ... error 自定義異常 >>> class MyError(Exception): ... def __str__(self): ... return '出錯啦.' ... >>> try: ... raise MyError() ... except MyError as e: ... print(e) ... 出錯啦.

 

錯誤異常的基本結構

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

執行流程:

  1. 若是出現錯誤,那麼就執行except代碼塊,而後在執行finally
  2. 若是沒有出現錯誤,那麼就執行else代碼塊,而後再執行finally
  3. 無論有沒有出現異常都會執行finally

異常分類

經常使用異常

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

總結

try.. ........   except

這種異常處理機制就是取代if那種方式,讓你的程序在不犧牲可讀性的前提下加強健壯性和容錯性

異常處理中爲每個異常定製了異常類型(python中統一了類與類型,類型即類),對於同一種異常,一個except就能夠捕捉到,能夠同時處理多段代碼的異常(無需‘寫多個if判斷式’)減小了代碼,加強了可讀性 

 

使用try..except的方式

1:把錯誤處理和真正的工做分開來
2:代碼更易組織,更清晰,複雜的工做任務更容易實現;
3:毫無疑問,更安全了,不至於因爲一些小的疏忽而使程序意外崩潰了;

4:try...except應該儘可能少用,由於它自己就是你附加給你的程序的一種異常處理的邏輯

5:這種東西加的多了,會致使你的代碼可讀性變差,只有在有些異常沒法預知的狀況下,才應該加上try...except,其餘的邏輯錯誤應該儘可能修正

相關文章
相關標籤/搜索