Python基礎之(九)錯誤和異常

錯誤

>>> for i in range(10)
 File "<stdin>", line 1
   for i in range(10)
                    ^
SyntaxError: invalid syntax

上面那句話由於缺乏冒號:,致使解釋器沒法解釋,因而報錯。這個報錯行爲是由Python的語法分析器完成的,而且檢測到了錯誤所在文件和行號(File "<stdin>", line 1),還以向上箭頭^標識錯誤位置(後面缺乏:),最後顯示錯誤類型。java

另外一種常見錯誤是邏輯錯誤。邏輯錯誤多是因爲不完整或者不合法的輸入致使,也多是沒法生成、計算等,或者是其它邏輯問題。python

當Python檢測到一個錯誤時,解釋器就沒法繼續執行下去,因而拋出提示信息,即爲異常。express

異常

下表中列出常見的異常編程

異常 描述
NameError 嘗試訪問一個沒有申明的變量
ZeroDivisionError 除數爲0
SyntaxError 語法錯誤
IndexError 索引超出序列範圍
KeyError 請求一個不存在的字典關鍵字
IOError 輸入輸出錯誤(好比你要讀的文件不存在)
AttributeError 嘗試訪問未知的對象屬性

NameError

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

Python中變量雖然不需在使用變量以前先聲明類型,但也須要對變量進行賦值,而後才能使用。不被賦值的變量,不能再Python中存在,由於變量至關於一個標籤,要把它貼到對象上纔有意義。this

ZeroDivisionError

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

SyntaxError

>>> for i in range(10)
      File "<stdin>", line 1
        for i in range(10)
                         ^
    SyntaxError: invalid syntax

這種錯誤發生在Python代碼編譯的時候,當編譯到這一句時,解釋器不能講代碼轉化爲Python字節碼,就報錯。spa

IndexError和KeyError

>>> a = [1,2,3]
    >>> a[4]
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    IndexError: list index out of range
    
    >>> d = {"python":"itdiffer.com"}
    >>> d["java"]
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    KeyError: 'java'

IOError

>>> f = open("foo")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    IOError: [Errno 2] No such file or directory: 'foo'

AttributeError

>>> class A(object): pass        #Python 3: class A: pass
    ... 
    >>> a = A()
    >>> a.foo
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'A' object has no attribute 'foo'

處理異常

#!/usr/bin/env python
# coding=utf-8

while 1:
   print "this is a division program."
   c = raw_input("input 'c' continue, otherwise logout:")
   if c == 'c':
       a = raw_input("first number:")
       b = raw_input("second number:")
       try:
           print float(a)/float(b)
           print "*************************"
       except ZeroDivisionError:
           print "The second number can't be zero!"
           print "*************************"
   else:
       break

try...except

對於上述程序,只看tryexcept部分,若是沒有異常發生,except子句在try語句執行以後被忽略;若是try子句中有異常可,該部分的其它語句被忽略,直接跳到except部分,執行其後面指定的異常類型及其子句。code

except後面也能夠沒有任何異常類型,即無異常參數。若是這樣,不論try部分發生什麼異常,都會執行except對象

except子句中,能夠根據異常或者別的須要,進行更多的操做。好比:索引

#!/usr/bin/env python
# coding=utf-8

class Calculator(object):
   is_raise = True
   def calc(self, express):
       try:
           return eval(express) #運行表達式
       except ZeroDivisionError:
           if self.is_raise:
               print "zero can not be division."        #Python 3:  "zero can not be division."
           else:
               raise #拋出異常信息

處理多個異常

Python 2:

    #!/usr/bin/env python
    # coding=utf-8

    while 1:
        print "this is a division program."
        c = raw_input("input 'c' continue, otherwise logout:")
        if c == 'c':
            a = raw_input("first number:")
            b = raw_input("second number:")
            try:
                print float(a)/float(b)
                print "*************************"
            except ZeroDivisionError:
                print "The second number can't be zero!"
                print "*************************"
            except ValueError:
                print "please input number."
                print "************************"
        else:
            break
            
 or
 
except (ZeroDivisionError, ValueError): #括號內也能夠包含多個異常
   print "please input rightly."
   print "********************"

打印異常,但程序不中斷

while 1:
        print "this is a division program."
        c = raw_input("input 'c' continue, otherwise logout:")
        if c == 'c':
            a = raw_input("first number:")
            b = raw_input("second number:")
            try:
                print float(a)/float(b)
                print "*************************"
            except (ZeroDivisionError, ValueError), e: #相似java
                print e
                print "********************"
        else:
            break

Python 3:

    while 1:
        print("this is a division program.")
        c = input("input 'c' continue, otherwise logout:")
        if c == 'c':
            a = input("first number:")
            b = input("second number:")
            try:
                print(float(a)/float(b))
                print("*************************")
            except (ZeroDivisionError, ValueError) as e:
                print(e)
                print("********************")
        else:
            break

else語句

>>> try:
    ...     print "I am try"        #Python 3: print("I am try"),
    ... except:                
    ...     print "I am except"
    ... else:                     #處理except就不會運行else
    ...     print "I am else"
    ... 
    I am try
    I am else

else語句應用,只有輸入正確的內容,循環纔會終止utf-8

#!/usr/bin/env python
    # coding=utf-8
    while 1:
        try:
            x = raw_input("the first number:")
            y = raw_input("the second number:")

            r = float(x)/float(y)
            print r
        except Exception, e:  #python3爲 Exception as e:
            print e
            print "try again."
        else:
            break

finally語句

若是有了finally,無論前面執行的是try,仍是except,最終都要執行它。相似java

>>> x = 10

    >>> try:
    ...     x = 1/0
    ... except Exception, e:        #Python 3:  except Exception as e:
    ...     print e        #Python 3: print(e)
    ... finally:
    ...     print "del x"        #Python 3:  print(e)
    ...     del x
    ... 
    integer division or modulo by zero
    del x

assert

assert是一句等價於布爾真的斷定,發生異常就意味着表達式爲假。當程序運行到某個節點的時候,就判定某個變量的值必然是什麼,或者對象必然擁有某個屬性等,簡單說就是判定什麼東西必然是什麼,若是不是,就拋出異常。

#!/usr/bin/env python
# coding=utf-8
            
if __name__ == "__main__":
    a = 8
    assert a < 0
    print a
    
Traceback (most recent call last):
  File "/Users/liuguoquan/Documents/workspace/PythonDemo/main.py", line 6, in <module>
    assert a < 0
AssertionError

這就是斷言assert的引用。什麼是使用斷言的最佳時機?有文章作了總結:

若是沒有特別的目的,斷言應該用於以下狀況:

  • 防護性的編程

  • 運行時對程序邏輯的檢測

  • 合約性檢查(好比前置條件,後置條件)

  • 程序中的常量

  • 檢查文檔

相關文章
相關標籤/搜索