检测无效的关键字参数

时间:2011-08-03 14:25:19

标签: python arguments keyword

我有以下功能:

def foo(**kwargs):
  if not kwargs:
    # No keyword arguments? It's all right. Set defaults here...
  elif ('start_index' or 'end_index') in kwargs:
    # Do something here...
  else:
    # Catch unexpected keyword arguments
    raise TypeError("%r are invalid keyword arguments" % (kwargs.keys())

问题:

我想确保唯一有效的关键字参数是start_indexend_index。其他任何东西都会引发错误,即使与有效的混合也是如此。什么是食谱配方,以确保只接受start_indexend_index?是的,我正在寻找食谱配方,但我不确定如何搜索它。我不确定使用if-elif-else结构是否正确。

4 个答案:

答案 0 :(得分:12)

为什么你需要**kwargs?刚

def foo(start_index=None, end_index=None):

并且Python将为您执行所有验证。

答案 1 :(得分:5)

为了完整起见,以下是仍然使用**kwargs的替代方案。

def foo(**kwargs):
  start_index = kwargs.pop('start_index', STARTINDEX_DEFAULT)
  end_index = kwargs.pop('end_index', ENDINDEX_DEFAULT)
  if kwargs:
    # Catch unexpected keyword arguments
    raise TypeError("%r are invalid keyword arguments" % (kwargs.keys())
  # Do something here...

但是,你不应该在你不完全需要时使用它,使用带有默认值的常规参数(如Roman Bodnarchuk的回答)。

当您可能需要这种情况时,您还需要使用*args,并且需要一种方法来区分关键字参数和任意人位置参数。以这种方式使用**kwargs 强制将关键字参数作为关键字传递;位置参数永远不会进入**kwargs

另一个原因是你可以真正区分默认参数和默认参数。 None通常用作参数的默认值,以指示“参数不适用”,但有时您实际上需要将None解释为默认值以外的其他值。检查**kwargs dict中是否存在密钥可以准确区分这些情况。 (另一种方法是创建object子类的实例,其唯一目的是成为该特定函数的特定参数的默认值。

答案 2 :(得分:1)

如果你真的想使用**kwargs,我会这样写:

def foo(**kwargs):
    # Define default values for all keys
    args = {'start_index': 0, 'end_index': -1}

    # Get the keys passed in that aren't in args
    extraargs = set(kwargs) - set(args)
    if extraargs:
        raise TypeError("Invalid arguments: %s" % list(extraargs))

    # Overwrite the default values with the passed-in values
    args.update(kwargs)

    # Now, do stuff with the values in args

但所有这些都是复制内置功能的复杂而缓慢的方法。除非你真的需要,否则不要这样做。

答案 3 :(得分:0)

无论如何从dict获取密钥就像使用.get一样简单。

kwargs.get('WIDTH',500)

这样一来,如果它没有找到WIDTH作为密钥就可以得到500.