防止变量关键字args中的拼写错误

时间:2015-02-01 07:37:27

标签: python python-2.x variadic-functions keyword-argument

在Python3中,我可以做到(感谢pep 3102):

def some_fun(a, *args, log=None, verbose=0):
    pass

并确保如果我将其称为:

some_fun(1, 2, 3, lob=debug_log)

我在意外关键字参数lob上收到类型错误。

在Python2上,我无法在任意参数列表之后使用仅关键字参数定义some_fun()。我必须这样做:

def some_fun(a, *args, **kw):
    log  = kw.get("log", None)
    verbose = kw.get("verbose", 0)

当正确调用时,这可以正常工作,但是当我向some_fun()提供一个或多个错误的关键字参数时,我希望得到类型错误,就像Python3一样。

3 个答案:

答案 0 :(得分:2)

不是使用.get()来检索值,而是使用.pop()并在弹出所有仅关键字参数后检查kw是否为空。

我使用了一个小辅助函数:

def check_empty_kwargs(kwargs):
   import inspect
   try:
      keys = kwargs.keys()
      assert len(keys) == 0
   except AssertionError:
      # uncomment if you want only one of the unexpected kwargs in the msg
      # keys = keys[:1]
      msg = "{0}() got an unexpected keyword argument{1} {2}".format(
         inspect.stack()[1][3], # caller name
         's' if len(keys) > 1 else '',
         ', '.join(["'{0}'".format(k) for k in keys]))
      raise TypeError(msg)

你会像以下一样使用它:

def some_fun(a, *args, **kw):
    log  = kw.pop("log", None)
    verbose = kw.pop("verbose", 0)
    check_empty_kwargs(kw)

调用它(假定debug_log已定义)

some_fun(1, 2, 3, lob=debug_log)
....
TypeError: some_fun() got an unexpected keyword argument 'lob'

回溯(当然)与Python3不同

答案 1 :(得分:1)

您可以检查允许的密钥,例如:

def f(a, *args, **kwargs):
    surplus = set(kwargs).difference(('log', 'foo', 'bar'))
    if surplus:
        raise TypeError('got unexpected keyword argument(s): ' + ', '.join(surplus))

答案 2 :(得分:1)

如果您有许多处理步骤,您可以将上述技术与另一个技术结合起来:

def f(a, *args, **kwargs):
    # we allow xyz, a, b
    xyz = kwargs.pop('xyz', 1)
    # now xyz must be gone, so we can only have a and/or b
    others = (lambda a=1, b=2: (a, b)(**kwargs))
    # either that was ok or it failed
    return xyz, others