dbr*_*dbr 5 python coding-style exception-handling
说我有这样的东西,它将未处理的异常发送到logging.critical()
:
import sys
def register_handler():
orig_excepthook = sys.excepthook
def error_catcher(*exc_info):
import logging
log = logging.getLogger(__name__)
log.critical("Unhandled exception", exc_info=exc_info)
orig_excepthook(*exc_info)
sys.excepthook = error_catcher
Run Code Online (Sandbox Code Playgroud)
有用:
import logging
logging.basicConfig()
register_handler()
undefined() # logs, then runs original excepthook
Run Code Online (Sandbox Code Playgroud)
但是,如果register_handler()
多次error_catcher
调用,则会在一个链中调用多个,并且记录消息会出现多次。
我可以想到几种方法,但是没有一种方法特别好(例如检查sys.excepthook
error_catcher函数是否是该函数,或者在模块上使用“ have_registered”属性以避免重复注册)
有推荐的方法吗?
拥有模块级“钩子已经注册”变量似乎是最简单、最可靠的方法。
其他可能的解决方案在某些(相当模糊)的情况下会失败 -sys.excepthook
如果应用程序注册了一个自定义函数,则检查是否是内置函数将失败excepthook
,在函数定义时存储原始函数excepthook
将破坏随后注册的 excepthook 函数。
import sys
_hook_registered = False
def register_handler(force = False):
global _hook_registered
if _hook_registered and not force:
return
orig_excepthook = sys.excepthook
def error_catcher(*exc_info):
import logging
log = logging.getLogger(__name__)
log.critical("Unhandled exception", exc_info=exc_info)
orig_excepthook(*exc_info)
sys.excepthook = error_catcher
_hook_registered = True
Run Code Online (Sandbox Code Playgroud)