sys.excepthook не работает в импортированных модулях - PullRequest
4 голосов
/ 27 марта 2011

Я пытаюсь разработать программу на 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, но мне все еще интересно: почему это происходит?

Ответы [ 2 ]

3 голосов
/ 29 марта 2011

Я сообщил об этой проблеме как об ошибке в 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
1 голос
/ 28 марта 2011

Я не могу воспроизвести вашу ошибку, даже если это произойдет в 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>

Работает просто отлично. Это работает для вас?

...