2016-02-22 95 views
1

來處理Python 3.5優雅的錯誤,我使用下面的代碼:回溯在Python 3.5

except: 
     exc_type, exc_value, exc_traceback = sys.exc_info() 
     # print("Unable to write feed_item in database") 
     # print(feeditem_insert_data) 
     error_insert_data = (
      prog_name, 'Unable to populate item for (feed id,ref_feed_id) (' 
         + str(feed_id) +',' + str(ref_feed_id) + ') in feed_item table' 
      , str(exc_type), str(exc_value), repr(traceback.format_tb(exc_traceback)), datetime.datetime.now() 
     ) 
     cur_error_log.execute(error_insert_stmt,error_insert_data) 
     continue 

在我的計劃中有許多地方添加該代碼後,我觀察怪異的行爲在程序運行長時間運行相同的數據不同於程序運行時間短。我無法確定地說在添加上面的代碼後出現這種行爲。

但我記得在某處讀到,如果我使用回溯比我不得不手動釋放內存。

如果上面的模塊在技術上是正確的或者需要做某些事情以避免問題,請諮詢。

+0

如果'continue'是你添加的部分,它可能是多餘的,或者會改變循環行爲。但除此之外,如果沒有其他代碼,就不可能診斷出什麼是錯的(如果有的話)。 – gil

+0

對不起,我不明白,請幫助我理解。繼續是忽略這個記錄並跳到下一個進行處理 - 它怎麼會有害或與診斷有關。 – Peter

+0

如果'except'後的代碼有更多的代碼,那麼'except'代碼塊中的continue會改變發生異常時的循環方式:如果沒有它,下面的代碼將在異常處理後執行;有了它,下面的代碼將被跳過。如果你在'except'塊之後沒有更多的代碼,那麼'continue'沒有任何區別,並且是多餘的。 – gil

回答

2

Python 3中關於異常的主要變化是不再需要使用sys.exc_info來獲取回溯。它現在在異常對象上作爲__traceback__屬性可用(這是可能的,因爲Python 3中的所有異常必須從基類Exception繼承,而舊版本的Python 2允許將任何東西視爲異常)。

所以,你可以用except Exception as e:取代你的except代碼的前兩行,然後用type(e)ee.__traceback__在錯誤報告代碼,而不是你從sys.exc_info得到的值。

將回溯作爲異常的屬性可能會對內存使用產生一些不利影響。具體來說,它會在當前的執行框架和異常之間創建一個引用循環。該框架引用異常(如果已將其綁定到局部變量),該異常將通過其屬性引用回溯,並且回溯引用框架。循環意味着參考計數系統超出範圍時不能立即回收存儲器。相反,它必須依賴循環垃圾回收器,這可能會很慢回收內存,甚至不會迴避(可以完全關閉它)。

爲了減少這個問題的影響,Python會自動刪除在塊尾部由except ExceptionType as e語句創建的異常變量。如果使用其他名稱創建對異常的引用,則可能需要自行清除它們以避免內存滯留時間長於需要的時間。

所以,如果你真的是有異常相關的記憶問題,嘗試在try塊的末尾添加del exc_value, exc_traceback,只是continue之前。或者,也可以切換到上述的except Exception as e語法,並且e(或您使用的任何名稱)將自動從本地名稱空間中刪除。

+0

非常感謝你的詳細回覆。我認爲del改變了行爲。我也會嘗試其他建議。 – Peter