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

Python: требуется kwarg, какое исключение для рейза?

Один из способов гарантировать, что метод вызывается с конкретным kwarg, будет выглядеть следующим образом:

def mymethod(self, *args, **kwargs):
    assert "required_field" in kwargs

Поднятие AssertionError не похоже на наиболее подходящую вещь. Есть ли согласованное встроенное исключение для обработки этого сообщения с хорошим сообщением?

Дополнительная информация: есть проблемы с подклассом сторонних производителей, в которых необходимо передать аргументы * args и ** kwargs kinda, поэтому создание "обязательного поля" позиционного аргумента на самом деле не является хорошим вариантом.

4b9b3361

Ответ 1

>>> def foo(bar): pass
... 
>>> foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() missing 1 required positional argument: 'bar'

Я бы просто пошел с TypeError..

Ответ 2

Стандартная библиотека, похоже, хочет поднять TypeError, когда она получает неправильное количество аргументов. Это, по сути, ваша проблема, поэтому я бы поднял это.

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

Обратите внимание, что python с радостью позволит вам вызвать позиционные аргументы по ключевому слову:

>>> def foo(a, b):
...     print a, b
... 
>>> foo(a=1, b=2)
1 2
>>> foo(b=1, a=2)
2 1

но я полагаю, что тогда все они должны ссылаться по ключевому слову (foo(2, a=2) не работает), который вам может не понадобиться.

Ответ 3

+1 для TypeError. Это то, что Python 3 повышает для требуемых аргументов только для ключевого слова:

>>> def foo(*, x):
...     pass
... 
>>> foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() needs keyword-only argument x
>>> foo(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() takes exactly 0 positional arguments (1 given)
>>> foo(x=2)

(Предложение TypeError уже было дано (и принято), я написал этот ответ, чтобы упомянуть эту функцию Python 3).

Ответ 4

Если вам нужно, чтобы это было ключевое слово, сделайте что-то вроде:

def mymethod(self,myrequired=None):
    if myrequired==None:
        #raise error
    #do other stuff down here

Вам не нужно действительно тянуть его из kwargs.

Ответ 5

Я думаю, что KeyError будет наиболее подходящим, потому что **kwargs - это dict.

>>> def foo(**kwargs):
...  print kwargs['abc']
...
>>> foo()
Traceback (most recent call last): 
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in foo
KeyError: 'abc'

Если поле действительно требуется, вы можете проверить его

try:
  kwargs['required']
except KeyError:
  raise KeyError('required is a Required Argument')