異常處理

1、異常和錯誤python

       一、語法錯誤(這種錯誤根本過不了python解釋器的語法檢測,必須在程序執行前就改正),以下示例:git

# 語法錯誤示範一
    if

    # 語法錯誤示範二
    def test:
        pass

    # 語法錯誤示範三
    print(haha
    # 錯誤提示都爲:SyntaxError: invalid syntax
語法錯誤

二、邏輯錯誤,以下示例:程序員

# 用戶輸入不完整(好比輸入爲空)或者輸入非法(輸入不是數字)
    num = input(">>: ")
    int(num)

    # 沒法完成計算
    res1 = 1/0
    res2 = 1 + 'str'

邏輯錯誤
邏輯錯誤

 

2、什麼是異常數據庫

       異常就是程序運行時發生報錯的信號,相似以下信息:django

    Traceback (most recent call last):安全

              File "E:/pythonDemo/1-basis/test20.py", line 43, in <module>網絡

                  int(num)框架

    ValueError: invalid literal for int() with base 10: 't'ide

  當異常發生以後,異常以後的代碼就不執行了。測試

  何時最容易出異常?

    當你要處理的內容不肯定的時候(有用戶參與、有外界數據接入 : 從文件中讀或者從網絡上獲取)。

  當有多行報錯的時候是爲何?

    在嵌套調用的過程當中,內部的代碼出了問題,外部全部的調用的地方都成爲報錯追溯信息的一部分。

  怎麼解決?

    從下往上找,首先找到本身寫的代碼碼出錯的那一行分析出錯緣由,或者把報錯的最後一行即錯誤類型和詳細提示本身百度,再結合報錯的那一行解決問題。

3、python中異常的種類

       在python中不一樣的異常能夠用不一樣的類型(python中統一了類與類型,類型即類)去標識,不一樣的類對象標識不一樣的異常,一個異常標識一種錯誤。以下示例:

# 觸發 IndexError
    l=['egon','aa']
    l[3]

    # 觸發 KeyError
    dic={'name':'egon'}
    dic['age']

    # 觸發 ValueError
    s='hello'
    int(s)

異常類型
異常類型

 

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

  

 ArithmeticError
    AssertionError
    AttributeError
    BaseException
    BufferError
    BytesWarning
    DeprecationWarning
    EnvironmentError
    EOFError
    Exception
    FloatingPointError
    FutureWarning
    GeneratorExit
    ImportError
    ImportWarning
    IndentationError
    IndexError
    IOError
    KeyboardInterrupt
    KeyError
    LookupError
    MemoryError
    NameError
    NotImplementedError
    OSError
    OverflowError
    PendingDeprecationWarning
    ReferenceError
    RuntimeError
    RuntimeWarning
    StandardError
    StopIteration
    SyntaxError
    SyntaxWarning
    SystemError
    SystemExit
    TabError
    TypeError
    UnboundLocalError
    UnicodeDecodeError
    UnicodeEncodeError
    UnicodeError
    UnicodeTranslateError
    UnicodeWarning
    UserWarning
    ValueError
    Warning
    ZeroDivisionError
更多異常

 

4、什麼是異常處理?爲何要進行異常處理?

       python解釋器檢測到錯誤,觸發異常(也容許程序員本身觸發異常),程序員編寫特定的代碼,專門用來捕捉這個異常(這段代碼與程序邏輯無關,與異常處理有關),若是捕捉成功則進入另一個處理分支,執行你爲其定製的邏輯,使程序不會崩潰,這就是異常處理。

       python解釋器去執行程序,檢測到了一個錯誤時,觸發異常,異常觸發後且沒被處理的狀況下,程序就在當前異常處終止,後面的代碼不會運行,誰會去用一個運行着忽然就崩潰的軟件。因此你必須提供一種異常處理機制來加強你程序的健壯性與容錯性。

5、如何進行異常處理

       首先須知,異常是由程序的錯誤引發的,語法上的錯誤跟異常處理無關,必須在程序運行前就修正。

5.1 使用if判斷式,以下示例:

 

num1 = input('>>: ') # 輸入一個字符串試試
    if num1.isdigit():
        int(num1) # 咱們的正統程序放到了這裏,其他的都屬於異常處理範疇
    elif num1.isspace():
        print('輸入的是空格,就執行我這裏的邏輯')
    elif len(num1) == 0:
        print('輸入的是空,就執行我這裏的邏輯')
    else:
        print('其餘情狀況,執行我這裏的邏輯')
    # 問題一:使用if的方式咱們只爲第一段代碼加上了異常處理,但這些if,跟你的代碼邏# 輯並沒有關係,這樣你的代碼會由於可讀性差而不容易被看懂
    # 問題二:這只是咱們代碼中的一個小邏輯,若是相似的邏輯多,那麼每一次都須要判斷這# 些內容,就會倒置咱們的代碼特別冗長。

總結:

  (1) if判斷式的異常處理只能針對某一段代碼,對於不一樣的代碼段的相同類型的錯誤你須要寫重複的if來進行處理。

  (2) 在你的程序中頻繁的寫與程序自己無關,與異常處理有關的if,會使得你的代碼可讀性極其的差。

  (3) if是能夠解決異常的,只是存在1,2的問題,因此,千萬不要妄下定論if不能用來異常處理。

5.2 python爲每一種異常定製了一個類型,而後提供了一種特定的語法結構用來進行異常處理,有以下幾種語法:

       1)基本語法

 

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

2)單分支:只能用來處理指定的異常狀況,若是非指定異常則沒法處理。以下示例:  

    l = ['login','register']
    for num,i in enumerate(l,1):
           print(num,i)

    try:
        num = int(input('num >>>'))
        print(l[num - 1])
    except ValueError :      # except處理的異常必須和實際報錯的異常是相同的
        print('請輸入一個數字')
   print(l[num - 1])

3)多分支:  

l = ['login','register']
    for num,i in enumerate(l,1):
        print(num,i)

    try:
        num = int(input('num >>>'))
        print(l[num - 1])
    except ValueError :    # 從上向下報錯的代碼只要找到一個和報錯類型相符的分支就執行這個分支中的代碼,而後直接退出分支
        print('請輸入一個數字')
    except IndexError :    # 若是找不到能處理和報錯類型相同的分支,會一直往下走,最後仍是沒有找到就會報錯
        print('只能輸入1或2')

4)多分支合併:  

l = ['login','register']
    for num,i in enumerate(l,1):
        print(num,i)

    try:
        num = int(input('num >>>'))
        print(l[num - 1])
    except (ValueError,IndexError) :
        print('您輸入的內容不合法')

5)萬能異常:在python的異常中,有一個萬能異常:Exception,他能夠捕獲任意異常,以下示例:  

 

s1 = 'hello'
    try:
        int(s1)
    except Exception as e:  # as語法  可以將具體錯誤信息打印出來
        print(e)

    萬能異常的另外一種寫法:
    try:
        name
        [][1]
        int('aaa')
    except:   # 至關於except Exception
        print(123)

6)多分支+萬能異常:萬能異常永遠放在異常處理的最下面,以下示例:  

try:
        pass
    except (ValueError,IndexError):
        print('針對性的處理')
    except Exception as e:
        print(e)
        print('通用性的處理')

7)else分支:當try中代碼不發生異常時執行else分支  

try:
        print('aaa')  # 給某某某發郵件
        # name
        # [][1]
        # 1/0
    except NameError:   # 網絡不穩定,郵箱地址錯誤
        print('name error')
    except IndexError:
        print('index error')
    except Exception as e:
        print('Exception')
    else:  # 當try中的代碼不發生異常的時候 走else分支  若是發送成功了 進行一些處理
        print('else')

8)finally分支:不管如何都會被執行  

def func():
        f = open('file')
        try:
           while True:
               for line in f:
                  if line.startswith('a'):
                      return line
        except:
           print('異常處理')
           finally:   # 即便return也會先執行fianlly中的代碼
              f.close()

  又一個示例以下:
  try:
        f = open('www','w')
        f.read()
   finally:   # 即便遇到報錯,程序結束,也會先執行finally中的代碼,而後再結束程序
        f.close()
        print('文件已經關閉了')

總結:finally用來回收一些操做系統的資源 : 數據庫鏈接、打開的文件句柄、網絡鏈接。

  9)主動拋出異常:是給其餘開發者用的,以下:

raise ValueError
    raise ValueError('你寫的不對')

    try:
        raise TypeError('類型錯誤')
    except Exception as e:
        print(e)
不要給用戶拋出異常,當你會寫相似django(別人寫的給程序員用的程序)的框架時能夠拋出異常。

  10)斷言(一種語法)

  # assert 條件(只能接受一個布爾值)
  assert 1 == 1
  assert 1 == 2

11)自定義異常(學完面向對象以後再學)

總結:異常處理的幾種狀況,以下:

  try ... except
  try ... except ... else
  try ... finally
  try ... except ... finally
  try ... except ... else ... finally

 

try..except的方式比較if的方式的好處:

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

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

使用try..except的方式

  1:把錯誤處理和真正的工做分開來;

  2:代碼更易組織,更清晰,複雜的工做任務更容易實現;

  3:毫無疑問,更安全了,不至於因爲一些小的疏忽而使程序意外崩潰了;

何時用異常處理?

  異常處理的忠告:在最外層的異常處理應該在全部的開發測試結束以後才放。

try:
      main()
  except Exception as e:
      把e報錯寫到文件裏

  try...except應該儘可能少用,由於它自己就是你附加給你的程序的一種異常處理的邏輯,與你的主要的工做是沒有關係的,這種東西加的多了,會致使你的代碼可讀性變差,只有在有些異常沒法預知的狀況下,才應該加上try...except,其餘的邏輯錯誤應該儘可能修正。

相關文章
相關標籤/搜索