【问题标题】:Python: required kwarg, which exception to raise?Python:需要 kwarg,要引发哪个异常?
【发布时间】:2012-11-16 18:49:11
【问题描述】:

确保使用特定 kwarg 调用方法的一种方法是:

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

提出AssertionError 似乎不是最合适的做法。是否有一致同意的内置异常来处理此问题并提供很好的错误消息?

更多信息:存在需要传递 *args 和 **kwargs kinda' 的 3rd-party 子类化问题,因此将“required_field”作为位置参数并不是一个好的选择。

【问题讨论】:

  • 我认为标准的做法是不要将其设为“默认参数”。
  • 已经有一些我不想弄乱的位置参数。
  • 更一般地说,也有一些情况是 kwargs 可以接受许多键,只有在满足特定条件时,其他关键字参数的存在或值才需要一些键。

标签: python exception


【解决方案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】:

    +1 表示类型错误。这就是 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 特性)。

    【讨论】:

    • 在这里提及 Python 3 关键字参数非常有用;人们可能会想到这个问题,当语言本身支持必需的关键字参数时,他们应该自己处理异常(当然,除非他们不幸被 Python 2 卡住了)。
    • 我最终在这里搜索所需 kwargs 的语法,所以我也 +1。
    【解决方案3】:

    标准库似乎喜欢在获得错误数量的参数时引发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) 不起作用)引用。

    【讨论】:

    • "**kwargs 本质上是在大多数情况下填充默认参数"。并不真地。这是一种用途,但**kwargs 还有其他几个重要用途:1) 在子类可能需要不同行为的超类中,2) 当您有一个长参数列表时,您不希望客户端必须记住参数**kwargs 避免了很多混乱。毫无疑问,还有其他人,但那些是首先浮现在脑海中的。前者(超类)最终导致我进入这个线程。
    【解决方案4】:

    我认为KeyError 是最合适的,因为**kwargsdict

    >>> 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')     
    

    【讨论】:

    • KeyError 通常直接应用于数据结构,而 OP 希望通知滥用函数签名。
    【解决方案5】:

    如果您需要它成为必需的关键字,请执行以下操作:

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

    你不应该真的需要从 kwargs 中提取它。

    【讨论】:

    • 只需添加*args,**kwargs :)
    猜你喜欢
    • 1970-01-01
    • 2015-08-31
    • 2011-12-22
    • 2022-11-09
    • 2011-05-05
    • 2012-11-16
    • 2015-04-02
    • 2018-06-06
    • 1970-01-01
    相关资源
    最近更新 更多