повторно вызвать исключение в Python

В очень хорошо написанной замечательной книге Роберта Смоллшира и Остина Бингема есть следующий код:

def convert(s):
    """Convert a string to an integer."""
    try:
        return int(s)
    except (ValueError, TypeError) as e:
        print("Conversion error: {}".format(str(e)), file=sys.stderr)
        raise

после этого автор включил следующую функцию string_log

def string_log(s):
    v = convert(s)
    return log(v)

и вывод string_log('ouch') выглядит следующим образом

Я не могу понять, какой оператор повышения точно работает?

Кроме того, автор говорит, что код, в котором первая функция выводит отрицательный код ошибки -1 в случае ValueError и TypeError, т.е. первая функция будет выглядеть следующим образом

import sys

def convert(s):
    """Convert a string to an integer."""
    try:
        return int(s)
    except (ValueError, TypeError) as e:
        print("Conversion error: {}".format(str(e)), file=sys.stderr)
        return -1

и чем если мы запустим следующее (без внесения каких-либо изменений string_log()) будет string_log('cat')

Является непитоновским, но почему?


person Nikhil Vidhani    schedule 28.07.2021    source источник
comment
Пожалуйста, исправьте отступ.   -  person not_speshal    schedule 28.07.2021
comment
название книги (The Python Apprentice?) было бы гораздо полезнее, чем ваш обзор.   -  person jonrsharpe    schedule 28.07.2021
comment
Вы спрашиваете, что делает raise без аргументов, или вы спрашиваете, почему создание исключения предпочтительнее, чем возврат специального значения?   -  person chepner    schedule 28.07.2021
comment
Отвечает ли это на ваш вопрос? поднять без аргументов   -  person Yevhen Kuzmovych    schedule 28.07.2021


Ответы (1)


Если convert возвращает -1 при ошибке, вы должны явно проверить это, чтобы string_log также не возвращал -1. Точно так же, как string_log ожидает, что convert вернет допустимую строку, так может и вызывающий. Распространение -1 может долгое время оставаться незамеченным, и если ошибка действительно возникает, становится неясным, в чем ее источник.

В случае исключения string_log не возвращает значение, если оно не перехватывает исключение; исключение продолжается вверх по стеку вызовов до тех пор, пока оно не будет перехвачено или интерпретатор не завершит работу с обратной трассировкой. Эта трассировка покажет точно источник исключения.


raise без аргументов просто вызывает самое последнее исключение, без необходимости писать что-то вроде

except (ValueError, TypeError) as e:
    print("Conversion error: {}".format(str(e)), file=sys.stderr)
    raise e

Здесь вы все равно используете e в вызове print, но если бы вы этого не сделали, вы могли бы написать

except (ValueError, TypeError):
    print("Something bad happened!")
    raise

без необходимости связывать исключение с явным именем.

person chepner    schedule 28.07.2021