#python #error-handling #traceback
Вопрос:
У меня есть следующий код
def _raise_exception(exception):
raise exception
def require_odd(n):
if n % 2 == 0:
_raise_exception(ValueError("n must be odd"))
print(require_odd(2))
Когда я запускаю его, он показывает
Traceback (most recent call last):
File "main.py", line 31, in <module>
print(require_odd(2))
File "main.py", line 29, in require_odd
_raise_exception(ValueError("n must be odd"))
File "main.py", line 25, in _raise_exception
raise exception
ValueError: n must be odd
Поскольку последняя строка кода из обратной трассировки избыточна, как мне вызвать исключение, чтобы оно показывало следующее?
Traceback (most recent call last):
File "main.py", line 31, in <module>
print(require_odd(2))
ValueError: n must be odd
В настоящее время я занимаюсь этим:
def _raise_exception(exception):
try:
raise exception
except Exception as e:
# Remove the last two calls (from this function and from the caller of this function)
stack_lines = traceback.format_stack()[:-2]
# Get the exception lines that contains the "Traceback (most recent call last):" in
# the first line and the "ValueError: n must be odd" in the last line
exception_lines = traceback.format_exception(e.__class__, e, e.__traceback__)
# Join the relevant lines, print to stderr and exit
print(''.join(exception_lines[:1] stack_lines exception_lines[-1:]), file=sys.stderr)
exit(1)
def require_odd(n):
if n % 2 == 0:
_raise_exception(ValueError("n must be odd"))
print(require_odd(2))
что действительно печатает
Traceback (most recent call last):
File "main.py", line 31, in <module>
print(require_odd(2))
ValueError: n must be odd
Но это просто кажется случайным. Есть ли лучший способ?
Комментарии:
1. Я не совсем понимаю, что вы подразумеваете под «избыточным» здесь. Трассировка стека функционирует так, как можно было бы надеяться, — она сбрасывает весь стек вызовов. Это, как правило, считается хорошей вещью , и среда выполнения Python проходит через множество проблем, чтобы предоставить вам эту информацию…
Ответ №1:
Не могли бы вы исключить эту _raise_exception
функцию?
Если бы ты просто убежал
if n % 2 == 0:
raise ValueError("n must be odd")
это устранило бы последнюю строку и стало бы ненужным шагом в этом процессе. Это не устранило бы среднюю линию, но, как правило, лучшие практики (о которых я знаю) заключаются в том, чтобы оставить стек в покое. Вам нужно как можно больше данных, когда что-то идет не так.
Дайте мне знать, если я что-то упущу, и я обновлю.
Комментарии:
1. Как вы сказали, это добавило
raise ValueError("n must be odd")
бы строку, которая , я думаю, является избыточной, так как последняя строка исключенияValueError: n must be odd
, но если нет лучшего варианта, я думаю, мне придется с этим разобраться.2. Просто кажется, что это большая работа, чтобы сделать что-то, что не является «красивым»для пользователя. Это немного избыточно, но, опять же, это дополнительная информация. И если вы ищете ошибку в более длинном стеке, наличие избыточности поможет вам легче привлечь ваше внимание.