Я хотел бы написать функцию на Python (2.6), которая может определить, вызывается ли она из кода обработки исключений где-то вверх по стеку.
Это для специализированного использования ведения журнала. В модуле Python logging
вызывающая сторона должна явно указать, что информация об исключении должна быть зарегистрирована (либо путем вызова logger.exception()
, либо с помощью ключевого слова exc_info
). Я хотел бы, чтобы мой регистратор делал это автоматически, в зависимости от того, вызывается ли он из кода обработки исключений.
Я думал, что ответом может быть проверка sys.exc_info(), но она также возвращает информацию об исключении из уже обработанного исключения. (Из документов: "Эта функция возвращает кортеж из трех значений, которые дают информацию о исключение, которое в данный момент обрабатывается... Если текущий фрейм стека не обрабатывает исключение, информация берется из вызывающего фрейма стека или вызывающего его, и так далее, пока не будет найден фрейм стека, который обрабатывает исключение. Здесь «обработка исключения» определяется как «выполнение или выполнение условия исключения».'")
Кроме того, поскольку я хочу, чтобы это было прозрачно для вызывающей стороны, я не хочу использовать exc_clear()
или что-либо еще в предложении except
.
Как правильно это сделать?
2 ответа
Если вы очищаете исключение, используя sys.exc_clear
в своих обработчиках исключений, тогда sys.exc_info
должно работать на вас. Например: если вы запустите следующий скрипт:
import sys
try:
1 / 0
except:
print sys.exc_info()
sys.exc_clear()
print sys.exc_info()
Вы должны увидеть этот вывод:
(, ZeroDivisionError('integer division or modulo by zero',), ) (None, None, None)
Обновление: я не верю, что существует простой ("прозрачный") способ ответить на вопрос "Работает ли обработчик исключений?" без каких-либо проблем, и, на мой взгляд, не стоит заморачиваться только ради регистрации. Конечно, легко ответить на вопрос "Было ли возбуждено исключение (в этом потоке)?", даже для каждого стека-фрейма (см. документацию по объектам фреймов).
Как и все в Python, исключение — это объект. Следовательно, вы можете сохранить (слабую!) ссылку на последнее обработанное исключение, а затем использовать sys.exc_info()
.
Примечание: в случае многопоточного кода у вас могут возникнуть проблемы с этим подходом. И могут быть и другие угловые случаи.
Однако явное лучше, чем неявное; Вы действительно уверены, что обработка ведения журнала исключений так же, как и обычная, является хорошей функцией для добавления в вашу систему?
По моему скромному мнению, нет.
Похожие вопросы
Новые вопросы
python
Python — это мультипарадигмальный многоцелевой язык программирования с динамической типизацией. Он предназначен для быстрого изучения, понимания и использования, а также обеспечивает чистый и унифицированный синтаксис. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Если у вас есть вопросы о версии Python, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas, NumPy) укажите это в тегах.