Что происходит при делении на ноль в Python
Что проверяют
Знаете ли вы, что Python здесь сознательно отступает от правил чисел с плавающей точкой, и обрабатываете ли вы случай, а не прячете его. Вопрос базовый, но по нему видно, читал ли человек про иерархию исключений.
Как отвечать
Деление на ноль поднимает ZeroDivisionError, наследника ArithmeticError. Это касается всех операций деления и обеих числовых веток:
1 / 0 # ZeroDivisionError: division by zero
1 // 0 # integer division or modulo by zero
1 % 0 # ZeroDivisionError
1.0 / 0.0 # float division by zero
divmod(1, 0) # тоже ZeroDivisionErrorОтдельно стоит подчеркнуть нюанс, который отличает Python от многих языков: 1.0 / 0.0 не даёт бесконечность, а 0.0 / 0.0 не даёт нечисло, хотя стандарт плавающей арифметики предписывает именно это. Язык выбрал исключение: тихо утёкшая в расчёты бесконечность почти всегда означает ошибку. Получить такие значения можно только явно, через float("inf") и math.nan.
Соседние библиотеки ведут себя иначе, и это хорошо смотрится в ответе: numpy при делении массива на ноль отдаёт бесконечность или нечисло с предупреждением, а не исключение, и режим настраивается через numpy.errstate. У decimal своё исключение DivisionByZero, наследник того же ZeroDivisionError, а реакция задаётся контекстом.
Обработка по ситуации: try/except ZeroDivisionError, где нулевой делитель ожидаем, и проверка заранее, где ноль означает битые данные.
Где спотыкаются
Ловят голый except или except Exception вокруг всей формулы. Под ту же ветку попадут опечатка в имени и TypeError от строки вместо числа, и настоящий баг уедет в продакшен под видом обработанного случая.
Второе: возвращают из обработчика строку с текстом ошибки. Функция, которая иногда отдаёт число, а иногда фразу, ломается у первого же вызывающего, который попробует это сложить. Возвращать надо None, значение по умолчанию или пробрасывать исключение выше.
Третье: пишут проверку на неравенство нулю и успокаиваются. Делитель, отличающийся от нуля на ничтожную величину, проверку пройдёт, а результат окажется бессмысленно огромным, так что проверять стоит допустимый диапазон, а не факт нуля.