python - 为什么 API 作者会阻止 Python 中的位置参数?
问题描述
使用 tensorflow 实现一些神经网络,我遇到了一个参数引起我注意的方法。我说的是(此处tf.nn.sigmoid_cross_entropy_with_logits
的文档)。
它接收的第一个参数作为第一个参数_sentinel=None
,根据文档:
_sentinel:用于防止位置参数。内部,请勿使用。
我知道通过使用此参数,必须命名下一个参数而不是位置参数是不是必须使用这个参数,但我的问题是。在哪些情况下防止位置参数有一些好处?他们使用它的主要目标是什么?因为我也可以跑
tf.nn.sigmoid_cross_entropy_with_logits(None, my_labels, my_logits)
都是位置的参数。无论如何,我想澄清一下,我的问题并不集中在 TensorFlow 中,这只是我找到的示例。
解决方案
位置参数按照参数的顺序耦合调用者和接收者。它使重构接收器参数的顺序更加困难。
例如,如果我有
def foo(a, b, c):
do_stuff(a,b,c)
我决定,出于某种原因,也许我想做一个部分功能或其他什么,最好有
def foo(b, a, c):
do_stuff(a,b,c)
但是现在我在野外有来电者,改变我的合同是非常粗鲁的,所以我被困住了。
Sandi Metz 在Practical Object-Oriented Design in Ruby 中也解决了这个问题。(我知道这是python,但是oop就是oop)
当代码[更改为使用关键字参数]时,它失去了对参数顺序的依赖,但它获得了对[关键字参数]中键名的依赖。这种变化是健康的。新的依赖比旧的更稳定,因此该代码面临被迫更改的风险较小。此外,也许出乎意料的是,[keywords] 提供了一个新的次要好处:散列中的键名提供了关于参数的明确文档。这是使用哈希的副产品,但它是无意的事实使它同样有用。此代码的未来维护者将不胜感激这些信息。
如果您有很多参数,关键字参数也很好。订单很容易出错。在作者看来,它也可能是一个更好的 API。
PEP-3102也解决了这个问题,但我发现从“为什么我会选择设计这样的东西”的角度来看,这个理由并不令人满意
当前的 Python 函数调用范例允许通过位置或关键字指定参数。参数可以通过名称显式填充,也可以通过位置隐式填充。
在某些情况下,函数需要可变数量的参数。Python 语言使用 'varargs' 语法 (*name) 支持这一点,它指定任何“剩余”参数作为元组传递给 varargs 参数。
对此的一个限制是,目前,必须先填充所有常规参数插槽,然后才能填充可变参数插槽。
这并不总是可取的。人们可以很容易地设想一个函数,它接受可变数量的参数,但也接受一个或多个关键字参数形式的“选项”。目前,唯一的方法是同时定义一个可变参数和一个“关键字”参数(**kwargs),然后从字典中手动提取所需的关键字。
推荐阅读
- c# - 我怎样才能像键盘记录器一样只挂钩隐藏键盘来读取键?(条形码扫描器)
- python - Python Pandas - 无法识别来自另一个数据框列中的列的字符串
- php - 查看 Google 日历中创建的每个活动的会议链接
- bash - 如何将 Bash 数组拆分为 Markdown 表中的多个列?
- algorithm - 恢复领先奇异向量的快速方法
- android - Dagger2 依赖注入:它如何在 Android 应用程序中工作?
- android - 在另一个活动中显示连接到一个活动的现有导航菜单
- algorithm - 在无向无环图中找到两个节点之间的最大权重边
- c - 打印在超出未定义长度字符数组边界的奇怪字符
- python - 加载 json 文件时出现 Json 解码器错误。虽然文件被验证为 Json。在 Python 中