Предположим, что в python у вас есть подпрограмма, которая принимает три именованных параметра (как ** args), но любые два из этих трех должны быть заполнены. Если заполняется только одно, это ошибка. Если все три, это ошибка. Какую ошибку вы бы подняли? RuntimeError, специально созданное исключение или другое?
Какое исключение можно повысить, если неверное количество аргументов передано в ** args?
Ответ 1
Помните, что вы можете подклассифицировать встроенные классы исключений Python (и TypeError
, несомненно, будет правильным встроенным классом исключений, чтобы поднять здесь - то, что Python повышает, если количество аргументов не соответствует сигнатуре, в нормальные случаи без форм *a
или **k
в сигнатуре). Мне нравится, что каждый пакет определяет свой собственный class Error(Exception)
, а затем конкретные исключения по мере необходимости могут умножать наследование по мере необходимости, например:
class WrongNumberOfArguments(thispackage.Error, TypeError):
Тогда я бы raise WrongNumberOfArguments
обнаружил такую проблемную ситуацию.
Таким образом, любой вызывающий абонент, который знает об этом пакете, может поймать thispackage.Error
, если им нужно иметь дело с какой-либо ошибкой, специфичной для пакета, тогда как другие вызывающие (предположительно выше в цепочке вызовов) вызов все еще поймают более общий TypeError
для устранения любых ошибок, таких как "неправильное количество аргументов, используемых при вызове функции".
Ответ 2
Почему бы просто не сделать то, что делает python?
>>> abs(1, 2, 3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: abs() takes exactly one argument (3 given)
Ответ 3
Если (как вы говорите в одном из комментариев), что это ошибка программиста, вы можете поднять AssertionError:
def two(**kwargs):
assert len(kwargs) == 2, "Please only provide two args"
Кстати, если у вас есть только три именованных аргумента, ** kwargs кажется странным способом сделать это. Более естественным может быть:
def two(a=None, b=None, c=None):
pass
Ответ 4
Я бы сделал конкретный. Вы можете поймать его и справиться с этим конкретным исключением, поскольку это особое обстоятельство, которое вы создали:)
Ответ 5
Я бы использовал значение ValueError или его подкласс: "При повышении, когда встроенная операция или функция получает аргумент, который имеет правильный тип, но неадекватное значение, и ситуация не описывается более точным исключением, например IndexError".
Передача 3 или 1 значений, когда требуется ровно 2, технически будет неуместным значением, если вы считаете все аргументы одним кортежем... По крайней мере, на мой взгляд!:)
Ответ 6
Я рекомендую настраиваемое исключение. Например:
class NeedExactlyTwo(ValueError):
pass
Тогда вы можете raise NeedExactlyTwo
в своем коде.
Обязательно запишите это в docstring для своей функции.