这是一项实现细节。
Python C API to retrieve arguments 区分位置参数和关键字参数。在内部,位置参数甚至没有名称。
用于检索
operator.add
函数(以及类似的
sub
)参数的代码如下:
PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)
正如您所看到的,它不包含任何参数名称。与operator.add
相关的整个代码如下:
#define spam2(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
PyObject *a1, *a2; \
if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
return AOP(a1,a2); }
spam2(op_add , PyNumber_Add)
#define spam2(OP,ALTOP,DOC) {#OP, op_##OP, METH_VARARGS, PyDoc_STR(DOC)}, \
{#ALTOP, op_##OP, METH_VARARGS, PyDoc_STR(DOC)},
spam2(add,__add__, "add(a, b) -- Same as a + b.")
正如您所看到的,a
和b
仅在文档字符串中使用。方法定义也未使用METH_KEYWORDS
标志,该标志对于使方法接受关键字参数是必要的。
一般来说,您可以安全地假设在您知道参数名称的基于Python的函数总是接受关键字参数(当然,有人可能会使用*args
解包进行恶意操作,但创建参数看起来正常的函数文档),而C函数可能会或可能不会接受关键字参数。具有多个参数或可选参数的函数很可能为后面/可选参数接受关键字参数。但是您几乎必须测试它。
您可以在python-ideas邮件列表上找到支持关键字参数的讨论。此外,还有一份来自Python创始人(也称为终身慈善独裁者)Guido van Rossum的声明:
我认为对于许多(大部分?)一参数和选定的二参数函数(很少有三个或更多参数的函数),这将降低可读性,就像 ord(char=x) 的示例所示。
实际上,我希望看到一种语法功能,以说明参数不能作为关键字参数给出(就像我们已经添加了语法来说明它必须是一个关键字一样)。
我认为添加关键字参数完全错误的一个领域:内置类型或 ABC 的方法并且是可重载的。例如,考虑 dict 上的 pop() 方法。由于参数名称目前未记录,如果有人子类化 dict 并覆盖此方法,或者如果他们创建另一个可变映射类来尝试使用鸭子类型模拟 dict,无论参数名称是什么都无所谓 - 所有调用者(期望 dict、dict 子类或 dict 类似的鸭子)都将在调用中使用位置参数。但是,如果我们记录 pop() 的参数名称,并且用户开始使用这些名称,则大多数 dict 子类和鸭子将突然断开连接(除非他们碰巧选择了相同的名称)。