python中的異常處理使用說明

來源:互聯網
上載者:User


Python的異常處理能力是很強大的,可向使用者準確反饋出錯資訊。在Python中,異常也是對象,可對它進行操作。所有異常都是基類Exception的成員,所有異常都從基類Exception繼承,而且都在exceptions模組中定義,Python自動將所有異常名稱放在內建命名空間中,所以程式不必匯入exceptions模組即可使用異常。
    一旦引發而且沒有捕捉SystemExit異常,程式執行就會終止。如果互動式會話遇到一個未被捕捉的SystemExit異常,會話就會終止。
    一、異常的捕獲
    異常的捕獲有以下幾種方法:
    1:使用try和except語句

 代碼如下 複製代碼

    try:
        block
    except [exception,[data…]]:
        block
    try:
        block
    except [exception,[data...]]:
        block
    else:
        block


該種異常處理文法的規則是:
• 執行try下的語句,如果引發異常,則執行過程會跳到第一個except語句。
• 如果第一個except中定義的異常與引發的異常匹配,則執行該except中的語句。
• 如果引發的異常不匹配第一個except,則會搜尋第二個except,允許編寫的except數量沒有限制。
• 如果所有的except都不匹配,則異常會傳遞到下一個調用本代碼的最高層try代碼中。
• 如果沒有發生異常,則執行else塊代碼。
範例程式碼:

 代碼如下 複製代碼

    try:
        f = open(“file.txt”,”r”)
    except IOError, e:
        print e


    捕獲到的IOError錯誤的詳細原因會被放置在對象e中,然後運行該異常的except代碼塊,也可以使用以下方法來捕獲所有的異常:

  

 代碼如下 複製代碼

  try:
        a=b
        b=c
    except Exception,ex:
        print Exception,":",ex

 

    使用except子句需要注意的事情,就是多個except子句截獲異常時,如果各個異常類之間具有繼承關係,則子類應該寫在前面,否則父類將會直接截獲子類異常,放在後面的子類異常也就不會執行到了。

    2:使用try跟finally

 

 代碼如下 複製代碼
   try:
        block
    finally:
        block


該語句的執行規則是:
• 執行try下的代碼。
• 如果發生異常,在該異常傳遞到下一級try時,執行finally中的代碼。
• 如果沒有發生異常,則執行finally中的代碼。

    第二種try文法在無論有沒有發生異常都要執行代碼的情況下是很有用的,例如我們在python中開啟一個檔案進行讀寫操作,我在操作過程中不管是否出現異常,最終都是要把該檔案關閉的。
    這兩種形式相互衝突,使用了一種就不允許使用另一種,而功能又各異。

    二、手工引發引發一個異常
    在Python中,要想引發異常,最簡單的形式就是輸入關鍵字raise,後跟要引發的異常的名稱。異常名稱標識出具體的類:Python異常是那些類的對象,執行raise語句時,Python會建立指定的異常類的一個對象,raise語句還可指定對異常對象進行初始化的參數,為此,請在異常類的名稱後添加一個逗號以及指定的參數(或者由參數構成的一個元組)。
範例程式碼:

 代碼如下 複製代碼

    try:
        raise MyError #自己拋出一個異常
    except MyError:
        print 'a error'
    raise ValueError,'invalid argument'

捕捉到的內容為:

 代碼如下 複製代碼

    type = VauleError
    message = invalid argument


    三、跟蹤查看異常
    發生異常時,Python能“記住”引發的異常以及程式的目前狀態,Python還維護著traceback(跟蹤)對象,其中含有異常發生時與函數呼叫堆疊有關的資訊,異常可能在一系列嵌套較深的函數調用中引發,程式調用每個函數時,Python會在“函數呼叫堆疊”的起始處插入函數名,一旦異常被引發,Python會搜尋一個相應的例外處理常式。
    如果當前函數中沒有例外處理常式,當前函數會終止執行,Python會搜尋當前函數的調用函數,並以此類推,直到發現匹配的例外處理常式,或者Python抵達主程式為止,這一尋找合適的例外處理常式的過程就稱為“堆棧輾轉開解”(Stack Unwinding)。解譯器一方面維護著與放置堆棧中的函數有關的資訊,另一方面也維護著與已從堆棧中“輾轉開解”的函數有關的資訊。

  

 代碼如下 複製代碼

  try:
        block
    except:
        traceback.print_exc()

 

    四、採用sys模組回溯最後的異常

  

 代碼如下 複製代碼
  import sys
    try:
        block
    except:
        info=sys.exc_info()
        print info[0],":",info[1]


或者以如下的形式:

   

 代碼如下 複製代碼
import sys
        tp,val,td = sys.exc_info()

    sys.exc_info()的傳回值是一個tuple, (type, value/message, traceback)
    這裡的type是異常的類型,value/message是異常的資訊或者參數,traceback包含調用棧資訊的對象,從這點上可以看出此方法涵蓋了traceback。

    以上都是錯誤處理的理論知識,接下來我們要動手設計一個自己的異常處理類,用來記錄異常日誌,將錯誤的日誌按照每小時一個檔案的頻率,儲存到我們指定的位置。代碼如下:

  

 代碼如下 複製代碼
  #coding:utf-8
    #基於python2.6
    import logging,os,time,traceback
    class LOG:
        def __init__(self,logger):
            self.fileHandlerName = ''
            self.fileHandler = None
            self.loggerName = logger
            self.logger = logging.getLogger(logger)
            self.logger.setLevel(logging.DEBUG)
            self.formatter = logging.Formatter("=========================ntime:%(asctime)s nlogger:%(name)s nlevel:%(levelname)s nfile:%(filename)s nfun:%(funcName)s nlineno:%(lineno)d nmessage:%(message)s")
            # 控制台
            ch = logging.StreamHandler()
            ch.setLevel(logging.DEBUG)
            ch.setFormatter(self.formatter)
            self.logger.addHandler(ch)
            path = os.path.abspath(os.path.dirname(__file__)) + '/log/'+self.loggerName+'/'
            print 'log path=',path
       
        def setfh(self):
            fname = time.strftime("%Y%m%d%H")
            if fname!=self.fileHandlerName:
                #移除原來的控制代碼
                if self.fileHandler!=None :
                    self.logger.removeHandler(self.fileHandler)
                #設定記錄檔儲存位置
                path = os.path.abspath(os.path.dirname(__file__)) + '/log/'+self.loggerName+'/'
                print path
                if os.path.isdir(path) == False:
                    os.makedirs(path)
                fh = logging.FileHandler(path+fname+'.log')
                fh.setLevel(logging.DEBUG)
                fh.setFormatter(self.formatter)
                self.logger.addHandler(fh)
                self.fileHandlerName = fname
                self.fileHandler = fh
        #格式化日誌內容
        def _fmtInfo(self,msg):
            if len(msg)==0:
                msg = traceback.format_exc()
                return msg
            else:
                _tmp = [msg[0]]
                _tmp.append(traceback.format_exc())
                return 'n**********n'.join(_tmp)
        #封裝方法
        def debug(self,*msg):
            _info = self._fmtInfo(msg)
            try:
                self.setfh()
                self.logger.debug(_info)
            except:
                print 'mylog debug:' + _info
        def error(self,*msg):
            _info = self._fmtInfo(msg)
            try:
                self.setfh()
                self.logger.error(_info)
            except:
                print 'mylog error:' + _info
        def info(self,*msg):
            _info = self._fmtInfo(msg)
            try:
                self.setfh()
                self.logger.error(_info)
            except:
                print 'mylog info:' + _info
        def warning(self,*msg):
            _info = self._fmtInfo(msg)
            try:
                self.setfh()
                self.logger.error(_info)
            except:
                print 'mylog warning:' + _info
           
    if __name__=='__main__':
        log = LOG('fight')
        try:
            print 1/0
        except:
            log.error() #使用系統自己的錯誤描述
        try:
            print 2/0
        except:
            log.error('搞錯了,分母不能為0')

#使用自己的錯誤描述


    運行一下,我們會在該檔案目錄下的log/fight下看到一個記錄檔

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.