Подтвердить что ты не робот

Должен ли я всегда указывать тип исключения в операторах `except`?

При использовании PyCharm IDE использование except: без типа исключения вызывает напоминание из среды IDE, что это предложение исключения Too broad.

Должен ли я игнорировать этот совет? Или это Pythonic всегда определяет тип исключения?

4b9b3361

Ответ 1

Почти всегда лучше указывать явный тип исключения. Если вы используете обнаженное предложение except:, вы можете в конечном итоге поймать исключения, отличные от тех, которые вы ожидаете поймать - это может скрыть ошибки или затруднить отладки программ, если они не выполняют то, что вы ожидаете.

Например, если вы вставляете строку в базу данных, вы можете поймать исключение, указывающее, что строка уже существует, поэтому вы можете сделать обновление.

try:
    insert(connection, data)
except:
    update(connection, data)

Если вы укажете голый except:, вы также поймаете ошибку сокета, указывающую, что сервер базы данных упал. Лучше всего только перехватывать исключения, которые вы знаете, как обращаться с ними - часто лучше для программы сбой в точке исключения, чем продолжать, но вести себя странно неожиданными способами.

Один случай, когда вы можете использовать голый except:, находится на верхнем уровне программы, которую нужно всегда запускать, например, на сетевом сервере. Но тогда вам нужно быть очень осторожным, чтобы регистрировать исключения, иначе невозможно будет понять, что происходит. В принципе, в программе, которая делает это, должно быть не более одного места.

Следствием всего этого является то, что ваш код никогда не должен делать raise Exception('some message'), потому что он заставляет клиентский код использовать except: (или except Exception:, что почти так же плохо). Вы должны определить исключение, специфичное для проблемы, которую вы хотите сигнализировать (возможно, наследуйте от какого-либо встроенного подкласса исключения, такого как ValueError или TypeError). Или вы должны поднять конкретное встроенное исключение. Это позволяет пользователям вашего кода быть осторожными в поиске только тех исключений, которые они хотят обработать.

Ответ 2

Вы не должны игнорировать советы, которые дает вам интерпретатор.

В PEP-8 Руководство по стилю для Python:

При перехвате исключений укажите конкретные исключения возможно вместо использования оголенного, за исключением:.

Например, используйте:

 try:
     import platform_specific_module 
 except ImportError:
     platform_specific_module = None 

Голый, кроме: предложение будет ловить исключения SystemExit и KeyboardInterrupt, что затрудняет прерывать программу с помощью Control-C и может маскировать другие проблемы. Если вы хотите поймать все исключения, которые сигнализируют программные ошибки, используйте кроме Исключения: (голый, кроме эквивалента, кроме BaseException:).

Хорошее эмпирическое правило состоит в том, чтобы ограничить использование голых "исключая" статей до двух случаи:

Если обработчик исключений будет распечатывать или регистрировать Выслеживать; по крайней мере, пользователь будет знать, что произошла ошибка. Если код должен выполнить некоторую работу по очистке, но затем разрешает исключение распространяются вверх с повышением. попробуйте... наконец, может быть лучший способ обработайте этот случай.

Ответ 3

Не указывать на Python это.

Вся суть исключений заключается в том, чтобы решить проблему как можно ближе к тому, где она была вызвана, насколько это возможно.

Таким образом, вы сохраняете код, который мог бы в исключительных условиях мог вызвать проблему и разрешение "рядом" друг с другом.

Дело в том, что вы не можете знать все исключения, которые могут быть брошены куском кода. Все, что вы можете знать, это то, что если он скажет, что файл не найден исключение, вы можете его поймать и предложить пользователю получить тот, который выполняет или отменяет функцию.

Если вы положите try catch на это, то независимо от того, какая проблема была в вашей файловой подпрограмме (только для чтения, разрешения, UAC, на самом деле не pdf и т.д.), каждый может зайти в ваш файл, не найденный catch, и ваш пользователь кричит "но он есть, этот код дерьмо"

Теперь есть пара ситуаций, когда вы можете поймать все, но их следует выбирать сознательно.

Они улавливаются, отменяют некоторые локальные действия (например, создание или блокирование ресурса (открытие файла на диске для записи, например), затем вы снова бросаете исключение, чтобы иметь дело на более высоком уровне)

Другой вам, вам все равно, почему это пошло не так. Печать, например. У вас может быть много общего, что, скажем, есть проблемы с вашим принтером, пожалуйста, разобраться, и не убивать приложение из-за этого. Оне аналогично тщетно, если ваш код выполнил серию отдельных заданий с использованием какого-то графика, вы бы не захотели, чтобы вся вещь погибла, потому что одна из задач потерпела неудачу.

Примечание. Если вы сделаете это выше, я не могу рекомендовать какое-то исключение, например. попробуйте поймать конец журнала, достаточно высоко.

Ответ 4

Вы также поймаете, например. Control-C с этим, так что не делайте этого, если вы снова не "выбросите" его. Однако в этом случае вам лучше использовать "finally".

Ответ 5

Всегда указывайте тип исключения, существует много типов, которые вы не хотите захватывать, например SyntaxError, KeyboardInterrupt, MemoryError и т.д.

Ответ 6

Вот места, где я использую, кроме типа

  • быстрое и грязное прототипирование

То, что основное использование в моем коде для исключенных исключений

  1. функция main() верхнего уровня, где я регистрирую каждое неперехваченное исключение

Я всегда добавляю это, так что производственный код не проливает стеки.

  1. между уровнями приложений

У меня есть два способа сделать это:

  • Первый способ сделать это: когда уровень более высокого уровня вызывает функцию более низкого уровня, он завершает вызовы в типизированных исключениях для обработки "верхних" исключений нижнего уровня. Но я добавляю общий оператор except, чтобы обнаруживать необработанные исключения нижнего уровня в функциях нижнего уровня.

Я предпочитаю это таким образом, мне легче определить, какие исключения должны были быть пойманы соответствующим образом: "лучше видеть" проблему, когда более низкий уровень регистрации регистрируется более высоким уровнем

  • Второй способ сделать это: каждая функция верхнего уровня уровней более низкого уровня имеет свой код, завернутый в общий, за исключением того, что он захватывает все необработанные исключения на этом конкретном уровне.

Некоторые коллеги предпочитают этот путь, поскольку он сохраняет исключения нижнего уровня в функциях более низкого уровня, где они "принадлежат".

Ответ 7

Попробуйте следующее:

try:
    #code
except ValueError:
    pass

Я получил ответ по этой ссылке, если кто-то еще столкнется с этой проблемой Проверьте это