2013-12-21 82 views
0

在我所有的Python主要腳本和模塊中,我一直試圖實現一種將未捕獲的異常記錄到引發異常的模塊的記錄器的方法。我在我所有的文件,這樣做同樣的方式:Python:sys.excepthook和在多個模塊中記錄未捕獲的異常

def log_unhandled_exception(*exc_info): 
    text = "".join(traceback.format_exception(*exc_info)) 
    logger.critical("An unhandled exception has caused this script to terminate prematurely. Here are the details: {0}".format(text)) 
    sys.exit(2) 

def some_function(): 
    # ... 

sys.excepthook = log_unhandled_exception 
logger = logging.getLogger("Module1") # or "Module2", "Module3", etc., each module has it's own logger 

當我遇到一個未捕獲的異常,我有時沒有得到預期的記錄。我認爲這與我導入模塊的順序有關:如果我導入module1然後導入module2,然後調用module2中的函數並運行一個異常,看起來我得到了module1的記錄器。相反,如果我顛倒了導入的順序(module2在module1之前),並且我嘗試了相同的測試(在module2中拋出異常),我正確地獲取了module2的記錄器。我會認爲後面的導入會優先(覆蓋前者的sys.excepthook參考),但不會。

我能夠通過給每個記錄器參考在每個模塊中的唯一名稱來解決這個問題(我猜...)。因此,要修改上面的代碼,這種模式運作而不考慮模塊導入的順序:

def log_unhandled_exception(*exc_info): 
    text = "".join(traceback.format_exception(*exc_info)) 
    module1_logger.critical("An unhandled exception has caused this script to terminate prematurely. Here are the details: {0}".format(text)) 
    sys.exit(2) 

def some_function(): 
    # ... 

sys.excepthook = log_unhandled_exception 
module1_logger = logging.getLogger("Module1") # or "Module2", "Module3", etc., each module has it's own logger 

這是正確的方式來達到我的預期目標,這是每一個模塊有它自己的記錄,每模塊使用它的記錄器記錄未捕獲的異常。

(實際的代碼更多樣化,並有原因的每一個模塊有自己的執行log_unhandled_exception的())

+0

這不是所有的這些單獨的'excepthook'都會彼此跺腳嗎?如果模塊'A'導入模塊'B','B'導入完成時,模塊'A'將使用任何'excepthook'從模塊'B'出來。 – user2357112

+0

是的,如果我在每個模塊中使用相同的變量名稱,基本上就是發生了什麼。我只是需要一些方法來捕捉每個模塊中的未捕獲異常,並且我願意接受任何設計更改/想法來完成此任務。 – CptSupermrkt

回答

1

sys.excepthook是全球對你的Python程序。您設置的最後一個值勝出。在模塊記錄器的不同文件中使用唯一名稱不會對其產生任何影響。