在默认值方面,在Python中使用 **kwargs
的正确方法是什么?
kwargs
返回一个字典,但设置默认值的最佳方法是什么,还是有一个?我应该只是作为字典访问它吗?使用get函数?
class ExampleClass:
def __init__(self, **kwargs):
self.val = kwargs['val']
self.val2 = kwargs.get('val2')
一个简单的问题,但我找不到好的资源 . 人们在我看过的代码中采用不同的方式,并且很难知道要使用什么 .
13 回答
你可以这样做
对于不在字典中的键,您可以将默认值传递给
get()
:但是,如果您计划使用具有特定默认值的特定参数,为什么不首先使用命名参数?
虽然大多数答案都是这样说的,例如,
是相同的”
这不是真的 . 在后一种情况下,
f
可以被称为f(23, 42)
,而前一种情况接受命名参数 only - 没有位置调用 . 通常,您希望允许调用者具有最大的灵活性,因此第二种形式(因为大多数答案断言)更可取:但情况并非总是如此 . 当你接受许多可选参数时,通常只有少数几个被传递,这可能是一个很好的想法(避免在你的呼叫站点发生意外和不可读的代码!)来强制使用命名参数 -threading.Thread
就是一个例子 . 第一种形式是如何在Python 2中实现它 .这个成语非常重要,在Python 3中它现在有了特殊的支持语法:
def
签名中单个*
之后的每个参数都只是关键字,也就是说,不能作为位置参数传递,而只能作为命名参数传递 . 所以在Python 3中你可以将上面的代码编写为:实际上,在Python 3中,您甚至可以使用非关键字参数,这些参数不是可选的(没有默认值的参数) .
但是,Python 2仍然有很长一段时间的 生产环境 生活,所以最好忘记让你在Python 2中实现Python 3语言直接支持的重要设计思想的技巧和习惯用法!
我建议这样的事情
然后以您想要的任何方式使用值
dictionaryA.update(dictionaryB)
将dictionaryB
的内容添加到dictionaryA
覆盖任何重复的密钥 .你做的
要么
如果使用
pop
,则可以检查是否发送了任何虚假值,并采取适当的操作(如果有) .使用** kwargs和默认值很容易 . 但是,有时候,你不应该首先使用** kwargs .
在这种情况下,我们并没有真正充分利用** kwargs .
以上是“为什么要这么麻烦?”宣言 . 它是一样的
当你使用** kwargs时,你的意思是关键字不仅是可选的,而且是有条件的 . 有比简单默认值更复杂的规则 .
当你使用** kwargs时,通常意味着更像下面的内容,其中简单的默认值不适用 .
由于
**kwargs
在参数数量未知时使用,为什么不这样做呢?这是另一种方法:
我认为在Python中使用
**kwargs
的正确方法是使用字典方法setdefault
,如下所示:这样,如果用户在关键字
args
中传递'val'或'val2',则会使用它们;否则,将使用已设置的默认值 .关注@srhegde建议使用setattr:
当预期类包含
acceptable
列表中的所有项时,此变体很有用 .如果你想将它与* args结合起来,你必须在定义的末尾保留* args和** kwargs .
所以:
@AbhinavGupta和@Steef建议使用
update()
,我发现这对处理大型参数列表非常有帮助:如果我们想检查用户是否未传递任何虚假/不支持的参数,该怎么办? @VinaySajip指出
pop()
可用于迭代处理参数列表 . 然后,任何剩下的争论都是虚假的 . 尼斯 .这是另一种可行的方法,它保留了使用
update()
的简单语法:unknown_args
是set
,其中包含默认值中不存在的参数名称 .处理未知或多个参数的另一个简单解决方案可以是: