Python 对于未知关键字参数,应引发哪个异常?

Python 对于未知关键字参数,应引发哪个异常?,python,python-3.x,keyword-argument,Python,Python 3.x,Keyword Argument,在Python中,将未知关键字参数传递给函数时应引发哪个异常?应该是吗?我看到Python本身会提升,但我不知道为什么 例如: def add(**kwargs): a = kwargs.pop('a', 0.) b = kwargs.pop('b', 0.) if kwargs: # what to raise here? raise SyntaxError('Unknown keyword arguments: ' + list(kw

在Python中,将未知关键字参数传递给函数时应引发哪个异常?应该是吗?我看到Python本身会提升,但我不知道为什么

例如:

def add(**kwargs):
    a = kwargs.pop('a', 0.)
    b = kwargs.pop('b', 0.)

    if kwargs:
        # what to raise here?
        raise SyntaxError('Unknown keyword arguments: ' + list(kwargs.keys()))
        # or ? 
        # raise TypeError('Unknown keyword arguments: ' + list(kwargs.keys()))

    return a + b

最合适的做法可能与Python本身的做法相同,即它会引发一个TypeError异常:

>>> def f(a, b):
...   pass
...
>>> f(a=1, b=2, c=3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() got an unexpected keyword argument 'c'
如果您提供的位置参数多于函数支持的参数,则也会引发TypeError,这也表明TypeError对此类错误的描述最好,并且是Python本身所期望的

当操作或函数应用于不适当类型的对象时引发。关联的值是一个字符串,提供有关类型不匹配的详细信息


最合适的做法可能与Python本身的做法相同,即它会引发一个TypeError异常:

>>> def f(a, b):
...   pass
...
>>> f(a=1, b=2, c=3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() got an unexpected keyword argument 'c'
如果您提供的位置参数多于函数支持的参数,则也会引发TypeError,这也表明TypeError对此类错误的描述最好,并且是Python本身所期望的

当操作或函数应用于不适当类型的对象时引发。关联的值是一个字符串,提供有关类型不匹配的详细信息


意外或缺少参数的相应错误为TypeError

虽然函数的具体类型只是函数,但Python在语义上使用了函数类型是其签名的公共类型,即参数->结果。例如,函数

def add(a, b): return a + b
具有类型a:Any,b:Any->Any。就类型而言,它可以与具有相同签名的任何其他函数交换。这也是由Python的可选代码编写的

调用函数意味着提供匹配的参数。这使用Python的规则来匹配参数的参数,例如addb=3,a=1仍然匹配adda:Any,b:Any


带有不兼容签名的调用,例如add1、2、3,意味着调用站点需要不同类型的函数,例如:Any、:Any、:Any->Any。这意味着调用的类型/签名与函数不匹配。因此,TypeError是适当的。

对于意外或缺少的参数,适当的错误是TypeError

虽然函数的具体类型只是函数,但Python在语义上使用了函数类型是其签名的公共类型,即参数->结果。例如,函数

def add(a, b): return a + b
具有类型a:Any,b:Any->Any。就类型而言,它可以与具有相同签名的任何其他函数交换。这也是由Python的可选代码编写的

调用函数意味着提供匹配的参数。这使用Python的规则来匹配参数的参数,例如addb=3,a=1仍然匹配adda:Any,b:Any


带有不兼容签名的调用,例如add1、2、3,意味着调用站点需要不同类型的函数,例如:Any、:Any、:Any->Any。这意味着调用的类型/签名与函数不匹配。因此,TypeError是合适的。

为什么不定义def adda=0.,b=0.:而不是手动模拟它?我认为SyntaxError会让人困惑-这与解析有关,而不是错误的参数。它肯定不应该是语法错误,因为它不是语法错误。syntaxerror所以使用TypeError。这样,代码可以很好地编译,语法没有任何错误,比如,分配给关键字,例如for=42关键字参数可以说是函数类型的一部分。这是处理错误的正常方法,所以这是最令人期待的。@MisterMiyagi这是一个MWE。在实际情况中,我需要将其保持为**kwargs,因为add是子类的重写方法。基类允许使用任意数量/组合的参数定义add。为什么不定义def adda=0.,b=0.:而不是手动模拟它?我认为SyntaxError会让人困惑-这与解析有关,而不是错误的参数。它肯定不应该是语法错误,因为它不是语法错误。syntaxerror所以使用TypeError。这样,代码可以很好地编译,语法没有任何错误,比如,分配给关键字,例如for=42关键字参数可以说是函数类型的一部分。这是处理错误的正常方法,所以这是最令人期待的。@MisterMiyagi这是一个MWE。在实际情况中,我需要将其保持为**kwargs,因为add是子类的重写方法。基类允许使用任意数量/组合的参数定义add。