Python 在函数体中接收**KWARG并解压参数,而不是简单的参数-为什么?

Python 在函数体中接收**KWARG并解压参数,而不是简单的参数-为什么?,python,scikit-learn,Python,Scikit Learn,我正在看scikit learn的sklearn.model\u selection.train\u test\u split的实现。Sklearn通常有高质量的代码,所以我经常阅读它来学习好的实践。但最近我发现了这样的东西: def系列测试分割(*阵列,**选项): """ ... """ n_数组=len(数组) 如果n_数组==0: raise VALUERROR(“至少需要一个数组作为输入”) test\u size=options.pop('test\u size',None) tra

我正在看
scikit learn
sklearn.model\u selection.train\u test\u split的实现。Sklearn通常有高质量的代码,所以我经常阅读它来学习好的实践。但最近我发现了这样的东西:

def系列测试分割(*阵列,**选项):
"""
...
"""
n_数组=len(数组)
如果n_数组==0:
raise VALUERROR(“至少需要一个数组作为输入”)
test\u size=options.pop('test\u size',None)
train\u size=options.pop('train\u size',无)
随机状态=options.pop('random_state',None)
stratify=options.pop('stratify',无)
shuffle=options.pop('shuffle',True)
如果选择:
raise TypeError(“传递的参数无效:%s”%str(选项))
# ...
我想知道,为什么选择这种方法?对我来说,这似乎是一种禁忌,但我认为sklearn开发人员知道他们在做什么,所以我可能错过了一些要点。为什么不干脆:

def列测试拆分(*数组,测试大小=无,列大小=无,…):
# ...

功能内解包有什么好处吗

我不能代表他们回答,但我相信这种形式的实现允许代码更灵活地进行更改。 该库正在开发过程中,并定期发布新版本。其中一些版本包括对现有方法的更改。此实现允许支持多个版本,而无需更改方法的签名或使用大量可选参数使其爆炸


也许还有其他我不知道的考虑,但这是我的猜测。希望能有所帮助。

要浓缩所有答案:

1) 函数头的冗长程度更低,需要的参数更少

2) 允许轻松扩展代码,而无需重新定义对函数的每次调用


3) 正如所建议的那样,它可以更好地控制错误,因为它们可以根据
**kwargs
的特定条目进行定制,因为这些条目丢失或格式错误

这是为了控制TypeError,以提供更容易理解的错误。我猜

根据您提出的方法,错误可能是:

TypeError:train\u test\u split()得到一个意外的关键字参数“not\u a\u valid\u kw”