当函数包含函数未使用的参数时,在函数中使用 kwargs

Use kwargs in a function when it contains arguments not-used by the function

假设我有以下功能:

def sub1(a,b,foo="bar"):
    print(a+b)
    print(foo)

def main(*args,**kwargs):
    a,b = args
    sub1(a,b,**kwargs)

我能做到

main(2,3) #5, bar
main(2,3,foo="baz") #5, baz

效果很好。

但是说我已经解析了一个额外的关键字参数,比如

main(2,3,qux="baz") #TypeError: sub1() got an unexpected keyword argument 'qux'

我们为什么要这样做?假设我有一个附加函数,它与 sub1 共享一些参数,但也有一些不同的参数

def sub2(foo,qux="fred"):
    print(foo)
    print(f"Hello {qux}")

然后不必再做

def main(*args,**sub1kwargs,**sub2kwargs):
   sub1(**sub1kwargs)
   sub2(**sub2kwargs)

我们可以只解析相同的 kwargs 并且函数只需要它所需要的:

def main(*args,**kwargs):
    sub1(**kwargs)
    sub2(**kwargs)

当然我们可以在将参数解析为 sub1 之前遍历参数列表(或者在 sub1 中使用 foo = kwargs.get("foo","bar)),但我想知道,如果我们可以避免这样做,只有一个 kwargs?

你可以做到,只需将 kwargs 添加到 sub1,它会自动解析你提供的任何命名参数,其余的将放入 kwargs:

def sub1(a, b, foo="bar", **kwargs):

这样您仍然可以使用或不使用 foo 调用 sub1,但您也可以使用或不使用其他参数调用它而不会导致错误。

main(1, 2, foo="hello")
  > 1, 2, "hello"
main(1, 2, qux="hello")
  > 1, 2, "bar"

"Explicit is better than implicit."

传递匿名 kwargs 并没有什么真正的好处。函数应该尽可能命名它们的关键字参数。像您的 main 这样的调用者不会通过保存奇数字节的代码来提高质量或可读性。 Process/filter kwargs 在需要的地方。要么

def main(*args, foo="bar", qux="baz"):
    sub1(*args, foo=foo)
    sub2(qux=qux)

def main(*args, **kwargs):
    sub1(*args, foo=kwargs.get("foo"))
    sub2(qux=kwargs.get("qux"))

会完成工作并且很容易理解。

当然,您可以定义一个函数,例如 (do NOT):

def sub1(a, b, **kwargs):
    print(a+b)
    print(kwargs.get("foo", "bar"))

这将允许调用者传递将被忽略的随机 kwargs,但它使调用者更难找出此函数真正需要的 kwargs。