Какое исключение следует выбрасывать при некорректных комбинациях аргументов в Python? [закрыто]
Я хотел бы обсудить лучшие практики по указанию недопустимых комбинаций аргументов в Python. Я столкнулся с несколькими ситуациями, когда у вас есть функция, например:
def import_to_orm(name, save=False, recurse=False):
"""
:param name: Название какого-либо внешнего объекта для импорта.
:param save: Сохранить объект ORM перед возвратом.
:param recurse: Попробовать импортировать связанные объекты. Поскольку
вам нужно, чтобы оригинальный объект имел ключ для связи, save должен
быть `True`, чтобы recurse был `True`.
:raise BadValueError: Если `recurse and not save`.
:return: Объект ORM.
"""
pass
Единственное неудобство заключается в том, что у каждого пакета есть свой собственный, обычно немного отличающийся BadValueError
. Я знаю, что в Java существует java.lang.IllegalArgumentException
— является ли общепринятым стандартом создание собственных BadValueError
в Python или существует метод, который предпочитается более широко?
5 ответ(ов)
Вы можете создать свой собственный класс исключения, унаследовав его от встроенного ValueError
, как показано в следующем примере:
class IllegalArgumentError(ValueError):
pass
Создание собственных исключений позволяет более точно описать ошибочные сценарии в вашем коде, особенно когда требуется обрабатывать специфические ошибки. Унаследовав от ValueError
, вы указываете, что ошибка связана с недопустимыми значениями, что делает ваш код более читаемым и понятным.
Если вам нужно перехватить именно эту ошибку, наличие специализированного имени, такого как IllegalArgumentError
, может быть очень полезным, так как это позволяет более детально реагировать на конкретные ситуации, сохраняя при этом возможность обработки общих ошибок.
Я думаю, что лучшим способом решить эту проблему является то, как это делает сам Python. Python выдает ошибку типа (TypeError). Например:
$ python -c 'print(sum())'
Traceback (most recent call last):
File "<string>", line 1, in <module>
TypeError: sum expected at least 1 arguments, got 0
Наш младший разработчик только что нашел эту страницу в результатах поиска Google по запросу "python exception wrong arguments", и меня удивляет, что очевидный (для меня) ответ так и не был предложен за десятилетие с тех пор, как был задан этот вопрос.
Ответ на ваш вопрос зависит от того, какая именно проблема с аргументами.
Если аргумент имеет неправильный тип, нужно вызывать TypeError
. Например, когда вместо одного из булевых значений вы получаете строку:
if not isinstance(save, bool):
raise TypeError(f"Аргумент save должен быть типа bool, а не {type(save)}")
Тем не менее, стоит отметить, что в Python мы редко делаем такие проверки. Если аргумент действительно недействителен, скорее всего, более глубокая функция сама выдаст ошибку. А если мы просто проверяем булевое значение, то пользователь кода может позже передать строку, зная, что непустые строки всегда считаются True, что может избавить его от преобразования типа.
Если аргументы имеют недопустимые значения, следует вызывать ValueError
. Это кажется более уместным в вашем случае:
if recurse and not save:
raise ValueError("Если recurse равно True, то save также должно быть True")
В данной конкретной ситуации вы можете сделать так, чтобы значение True
для recurse
подразумевало значение True
для save
. Поскольку я бы счел это восстановлением от ошибки, вы также можете записать предупреждение в лог:
if recurse and not save:
logging.warning("Некорректные аргументы в import_to_orm() - если recurse равно True, то и save должно быть True")
save = True
В основном я видел, что в такой ситуации используется встроенное исключение ValueError
.
В данном случае вам, скорее всего, следует использовать ValueError
(в полном виде raise ValueError()
), но это зависит от типа некорректного значения. Например, если вы написали функцию, которая принимает только строки, и пользователь передал целое число вместо строки, то в этом случае лучше использовать TypeError
. Если же пользователь ввел неверное значение (то есть оно имеет правильный тип, но не соответствует определенным условиям), то лучше всего подойдет ValueError
. Также ValueError
может помочь предотвратить возникновение других исключений. Например, вы можете использовать ValueError
, чтобы предотвратить возникновение ZeroDivisionError
, как в следующем примере:
def function(number):
if not isinstance(number, (int, float)):
raise TypeError("number must be an integer or float")
if number == 5:
raise ValueError("number must not be 5")
else:
return 10 / (5 - number)
P.S. Чтобы посмотреть список встроенных исключений в Python, посетите эту ссылку: https://docs.python.org/3/library/exceptions.html (это официальный источник данных Python).
Вручную вызов (бросание) исключения в Python
Поймать и вывести полный трейсбек исключения в Python без остановки/выхода из программы
Как напечатать исключение в Python?
Как проверить, существует ли переменная?
Как протестировать, что функция Python вызывает исключение?