【问题标题】:sys.excepthook doesn't work in imported modulessys.excepthook 在导入的模块中不起作用
【发布时间】:2011-07-24 00:45:12
【问题描述】:

我正在尝试设计一个 Python 程序,该程序使用日志记录模块记录所有未捕获的异常。我通过使用 sys.excepthook 函数来覆盖默认的异常处理来做到这一点。我注意到如果我直接从命令行运行程序,它工作正常,但如果我尝试导入文件,它就不起作用。似乎 sys.excepthook 函数不知道日志记录模块。这是一个例子:

#! /usr/bin/env python2.7
import logging, sys

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.FileHandler("test.log"))

print "outside of exception handler: logger = %s" % logger

def handleException(excType, excValue, traceback):
    #global logger  # this function doesn't work whether or not I include this line
    print "inside exception handler: logger = %s" % logger
    logger.error("Uncaught exception", exc_info=(excType, excValue, traceback))

sys.excepthook = handleException

logger.debug("starting")
asdf    # create an exception

如果我从命令行 (./loggingTest.py) 运行它,它工作正常。异常被记录,我看到了这个输出:

outside of exception handler: logger = <logging.RootLogger object at 0x7f2022eab950>
inside exception handler: logger = <logging.RootLogger object at 0x7f2022eab950>

但是,如果我运行 Python 解释器并尝试导入文件 (import loggingTest),它的行为会很奇怪。没有记录异常,我看到了这个:

outside of exception handler: logger = <logging.RootLogger object at 0x7f8ab04f3ad0>
inside exception handler: logger = None
Error in sys.excepthook:
Traceback (most recent call last):
  File "loggingTest.py", line 13, in handleException
    logger.error("Uncaught exception", exc_info=(excType, excValue, traceback))
AttributeError: 'NoneType' object has no attribute 'error'

Original exception was:
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "loggingTest.py", line 18, in <module>
    asdf    # create an exception
NameError: name 'asdf' is not defined

我也许可以通过在 sys.excepthook 中再次导入日志记录模块来解决这个问题,但我仍然很好奇:为什么会发生这种情况?

【问题讨论】:

    标签: python exception logging


    【解决方案1】:

    我将此问题报告为Python bug tracker 上的错误。到目前为止,有人回应说 Python 2.7 和 2.7.1 之间肯定存在变化,他认为这是预期的行为。他建议使用这样的方法来记录所有异常:

    def handleException(excType, excValue, traceback, logger=logger):
        logger.error("Uncaught exception", exc_info=(excType, excValue, traceback))
    
    sys.excepthook = handleException
    

    【讨论】:

      【解决方案2】:

      我无法重现您的错误,即使它发生在 exhook.py 中。这是exhook.py

      #! /usr/bin/env python2.7
      import logging, sys, traceback as tb
      
      logger = logging.getLogger()
      logger.setLevel(logging.DEBUG)
      logger.addHandler(logging.FileHandler("test.log"))
      
      print "outside of exception handler: logger = %s" % logger
      
      def handleException(excType, excValue, traceback):
          #global logger  # this function doesn't work whether or not I include this line
          tb.print_exception(excType, excValue, traceback)
          print "inside exception handler: logger = %s" % logger
          logger.error("Uncaught exception", exc_info=(excType, excValue, traceback))
      
      sys.excepthook = handleException
      
      raise Exception
      

      然后:

      Python 2.7 (r27:82525, Jul  4 2010, 09:01:59) [MSC v.1500 32 bit (Intel)] on win
      32
      Type "help", "copyright", "credits" or "license" for more information.
      >>> import exhook
      outside of exception handler: logger = <logging.RootLogger object at 0x02AB0A70>
      
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "exhook.py", line 18, in <module>
          raise Exception
      Exception inside exception handler: logger = <logging.RootLogger object at 0x02AB0A70>
      

      它工作得很好。这对你有用吗?

      【讨论】:

      • 我这样做时效果很好。如果我在定义 sys.excepthook 的同一文件中生成异常,它将不起作用。
      • @mikez302:对不起,我改变了答案,但不管怎样都可以。
      • 即使在您修改后,如果我直接运行它,您的脚本也可以正常工作,但如果我导入它就无法正常工作。
      • @mikez302:好吧,我刚刚从 Python 2.7 升级到 2.7.1,你猜怎么着——现在我遇到了和你一样的错误!恭喜,你找到了回归 :-)
      • 我报告了这个错误。你可以在bugs.python.org/issue11705查看错误报告
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-11
      • 1970-01-01
      • 1970-01-01
      • 2015-04-30
      • 1970-01-01
      • 2021-09-01
      • 1970-01-01
      相关资源
      最近更新 更多