十7、深刻Python異常處理

「@Author:BY Runsen」git

在Python 中的錯誤和異常是什麼?github

一般來講,程序中的錯誤至少包括兩種,一種是語法錯誤,另外一種則是異常。web

語法錯誤

所謂語法錯誤,你應該很清楚,也就是你寫的代碼不符合編程規範,沒法被識別與執行,好比下面這個例子的語法錯誤面試

下面的代碼沒法被識別和執行數據庫

if name is not None
    print(name)

上面的代碼If 語句漏掉了冒號,不符合 Python 的語法規範,因此程序就會報錯invalid syntax編程

異常

異常則是指程序的語法正確,也能夠被執行,但在執行過程當中遇到了錯誤,拋出了異常。json

好比,最多見的除數不能爲0。變量沒有定義。數據類型的運算。小程序

10 / 0
Traceback (most recent call last):
  File "<stdin>", line 1in <module>
ZeroDivisionError: integer division or modulo by zero

order * 2
Traceback (most recent call last):
  File "<stdin>", line 1in <module>
NameError: name 'order' is not defined

1 + [12]
Traceback (most recent call last):
  File "<stdin>", line 1in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'list'

上面報的是常見的報錯,好比ZeroDIvision NameError 和 typeError微信

還有不少其餘異常的類型如keyError 字典的鍵找不到和FileNotFoundError 文件不存在app

try except

使用Python的異常處理語句,能夠很是優雅地處理髮生的異常。

下面是Python的異常處理語句的模板語法

try:
    # 可能觸發異常的語句塊
except:  
    # 這裏執行異常處理的相關代碼,打印輸出等
else:
    # 若是沒有異常則執行else中的代碼
finally:
    # 無論代碼是否異常,都會執行,通常是資源的關閉和釋放

首先,檢測try語句塊中的錯誤,except語句捕獲異常信息並處理。若是在try子句執行時沒有發生異常,Python將執行else語句後的語句,而後控制流經過整個try語句。

好比看下面的例子。

try:
    print(a*2)
except TypeError:
    print("TypeError")
except:
    print("Not Type Error & Error noted")
    
Not Type Error & Error noted

因爲a沒有定義,報的是NameError而不是TypeError。異常最終被except:部分的程序捕捉。

這裏,Runsen補充一下很是重要的知識點:

拋出異常

拋出異常模板:raise 異常類名(附加異常信息) 。下面是示例代碼:

s = "RunsenRunsen"
try:
    if len(s) > 10:
        raise Exception("超過10個字符")
except Exception as err:
    print(err)
    
超過10個字符

有時產生的異常,不想在當前處理,那麼就可使用raise拋出異常。下面是示例代碼:

def division():
    a = float(input('輸入被除數:'))
    b = float(input("輸入除數:"))
    if a < 0 or b < 0:
        raise Exception("我是Runsen,要求:輸入的數不能小於0。"#出現負數拋出異常。
    c = a / b
    print(a,'÷',b,'=',c)
    
try:
    division()
except Exception as d:
    print('出錯了,',d)
    
運行結果:
輸入被除數:5
輸入除數:-1
出錯了, 我是小學生,輸入的數不能小於0。
輸入被除數:5
輸入除數:0
出錯了, float division by zero

萬能異常

由於異常分了不一樣的種類,若是不知道,那麼使用exception異常處理就足夠了,它能夠接收任何異常

value = 'hello'
try:
    int(value)
#萬能異常處理  
except Exception as e:
    print(e)

自定義異常

實際開發中,有時候系統提供的異常類型不能知足開發的需求。這時候你能夠經過建立一個新的異常類來擁有本身的異常。異常類繼承自 Exception 類,能夠直接繼承,或者間接繼承。

# 自定義異常類 MyError ,繼承普通異常基類 Exception
class MyError(Exception):
        def __init__(self, value):
            self.value = value
        def __str__(self):
            return repr(self.value)
try:
    num = input("請輸入數字:")
    if not num.isdigit():  # 判斷輸入的是不是數字
        raise MyError(num)  # 輸入的若是不是數字,手動指定拋出異常
except MyError as e:
    print("MyError:請輸入數字。您輸入的是:", e.value)

請輸入數字:1
請輸入數字:Runsen
MyError:請輸入數字。您輸入的是:Runsen

擴展

大型社交網站的後臺,須要針對用戶發送的請求返回相應記錄。用戶記錄每每儲存在 key-value 結構的數據庫中,每次有請求過來後,咱們拿到用戶的 ID,並用 ID 查詢數據庫中此人的記錄,就能返回相應的結果。而數據庫返回的原始數據,每每是 json string 的形式,這就須要咱們首先對 json string 進行 decode(解碼),你可能很容易想到下面的方法:

import json
raw_data = queryDB(uid) # 根據用戶的 id,返回相應的信息。queryDB這裏是一個函數
data = json.loads(raw_data)

上面的代碼是否是就足夠呢?

json.loads()函數中,若是輸入的字符串不符合規範,那麼就沒法解碼,就會拋出異常。

raw_data必定是json嗎?,所以寫以前就應該考慮如何處理異常

try:
    data = json.loads(raw_data)
except JSONDecodeError as err:
    print('JSONDecodeError: {}'.format(err))

「附件:異常類列表(來源:菜鳥教程)」

異常名稱 描述


BaseException 全部異常的基類
SystemExit 解釋器請求退出
KeyboardInterrupt 用戶中斷執行(一般是輸入^C)
Exception 常規錯誤的基類
StopIteration 迭代器沒有更多的值
GeneratorExit 生成器(generator)發生異常來通知退出
StandardError 全部的內建標準異常的基類
ArithmeticError 全部數值計算錯誤的基類
FloatingPointError 浮點計算錯誤
OverflowError 數值運算超出最大限制
ZeroDivisionError 除(或取模)零 (全部數據類型)
AssertionError 斷言語句失敗
AttributeError 對象沒有這個屬性
EOFError 沒有內建輸入,到達EOF 標記
EnvironmentError 操做系統錯誤的基類
IOError 輸入/輸出操做失敗
OSError 操做系統錯誤
WindowsError 系統調用失敗
ImportError 導入模塊/對象失敗
LookupError 無效數據查詢的基類
IndexError 序列中沒有此索引(index)
KeyError 映射中沒有這個鍵
MemoryError 內存溢出錯誤(對於Python 解釋器不是致命的)
NameError 未聲明/初始化對象 (沒有屬性)
UnboundLocalError 訪問未初始化的本地變量
ReferenceError 弱引用(Weak reference)試圖訪問已經垃圾回收了的對象
RuntimeError 通常的運行時錯誤
NotImplementedError 還沒有實現的方法
SyntaxError Python 語法錯誤
IndentationError 縮進錯誤
TabError Tab 和空格混用
SystemError 通常的解釋器系統錯誤
TypeError 對類型無效的操做
ValueError 傳入無效的參數
UnicodeError Unicode 相關的錯誤
UnicodeDecodeError Unicode 解碼時的錯誤
UnicodeEncodeError Unicode 編碼時錯誤
UnicodeTranslateError Unicode 轉換時錯誤
Warning 警告的基類
DeprecationWarning 關於被棄用的特徵的警告
FutureWarning 關於構造未來語義會有改變的警告
OverflowWarning 舊的關於自動提高爲長整型(long)的警告
PendingDeprecationWarning 關於特性將會被廢棄的警告
RuntimeWarning 可疑的運行時行爲(runtime behavior)的警告
SyntaxWarning 可疑的語法的警告
UserWarning 用戶代碼生成的警告

本文已收錄 GitHub,傳送門~[1] ,裏面更有大廠面試完整考點,歡迎 Star。



Reference

[1]

傳送門~: https://github.com/MaoliRUNsen/runsenlearnpy100


今天的文章到這裏就結束了,若是喜歡本文的話,請來一波素質三連,給我一點支持吧(關注、在看、點贊)。

更多的文章

點擊下面小程序


- END -




本文分享自微信公衆號 - Python之王(sen13717378202)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索