Можно ли вызывать встроенное исключение, но с другим сообщением в Python? - PullRequest
22 голосов
/ 02 февраля 2010

Можно ли вызвать встроенное исключение с пользовательским текстом? или поднять встроенное предупреждение также с пользовательским текстом?

Документация гласит:

исключение ValueError: Возникает, когда встроенная операция или функция получает аргумент (…)

Подразумевается ли, что только встроенные операции должны вызывать исключение ValueError?

На практике я понимаю, что безопасно создавать класс исключений, который наследуется от ValueError или Exception. Но нормально ли это не делать, а напрямую вызывать ValueError («пользовательский текст»)?

Так как ValueError является встроенным, повышение ValueError (с пользовательским текстом) позволяет пользователям быстро увидеть, какая проблема связана с пользовательским типом исключения (что-то вроде «ValueErrorSpecificModule», который не является стандартным).

Ответы [ 3 ]

25 голосов
/ 02 февраля 2010

Нет ничего плохого в том, чтобы делать что-то вроде:

raise ValueError("invalid input encoding")

На самом деле, я делаю это довольно часто, когда пишу первый проход какого-то кода. Основная проблема с этим заключается в том, что клиенты вашего кода испытывают трудности с точностью обработки своих исключений; чтобы поймать это конкретное исключение, им придется выполнить сопоставление строк в объекте исключения, которое они поймали, что очевидно хрупко и утомительно. Таким образом, было бы лучше ввести собственный подкласс ValueError; это может все еще быть поймано как ValueError, но также и как более определенный класс исключения.

Общее правило гласит: всякий раз, когда у вас есть такой код:

raise ValueError('some problem: %s' % value)

Вам, вероятно, следует заменить его на что-то вроде:

class SomeProblem(ValueError):
    """
    Raised to signal a problem with the specified value.
    """
# ...
raise SomeProblem(value)

Можно сказать, что тип исключения указывает , что пошло не так, в то время как сообщение / атрибуты указывают , как , оно пошло не так.

4 голосов
/ 02 февраля 2010

Все нормально, и я делаю это все время. Я нахожу менее удивительным видеть TypeError, чем MySpecialTypeError во многих ситуациях.

На странице , на которую вы ссылались , я не вижу фразы "встроенный":

exception TypeError: Raised when an operation or function is applied to an object of inappropriate type. The associated value is a string giving details about the type mismatch.

Возможно, кто-то видел ваш вопрос и уже исправил документацию.
РЕДАКТИРОВАТЬ: Похоже, вы могли вставить документацию для ValueError вместо TypeError

2 голосов
/ 02 февраля 2010

Это совершенно нормально.

Однако вы можете создать свой собственный подкласс, чтобы отличать его от встроенных исключений

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

Повышение подкласса KeyError облегчает понимание того, что в реализации есть ошибка, а не то, что ключ просто отсутствует в вашем объекте

...