gpt4 book ai didi

python - 请解释为什么这两个内置函数在传入关键字参数时表现不同

转载 作者:太空狗 更新时间:2023-10-29 21:24:53 26 4
gpt4 key购买 nike

考虑这些不同的行为::

>> def minus(a, b):
>> return a - b

>> minus(**dict(b=2, a=1))
-1

>> int(**dict(base=2, x='100'))
4

>> import operator
>> operator.sub.__doc__
'sub(a, b) -- Same as a - b.'
>> operator.sub(**dict(b=2, a=1))
TypeError: sub() takes no keyword arguments

为什么 operator.sub 的行为与 int(x, [base]) 不同?

最佳答案

这是一个实现细节。 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.")

如您所见,唯一使用ab 的地方是在文档字符串中。方法定义也不使用方法接受关键字参数所必需的 METH_KEYWORDS 标志。

一般来说,您可以安全地假设一个您知道参数名称的基于 python 的函数将总是接受关键字参数(当然有人可以用 *args 解包但创建一个函数文档,其中参数看起来很正常),而 C 函数可能接受也可能不接受关键字参数。具有多个参数或可选参数的函数很有可能接受后面/可选参数的关键字参数。但是您几乎必须对其进行测试。

您可以在 python-ideas mailinglist 上找到有关支持关键字参数的讨论。 . Guido van Rossum(Benevolent Dictator For Life 又名 Python 的创造者)在其上也发表了声明:

Hm. I think for many (most?) 1-arg and selected 2-arg functions (and rarely 3+-arg functions) this would reduce readability, as the example of ord(char=x) showed.

I would actually like to see a syntactic feature to state that an argument cannot be given as a keyword argument (just as we already added syntax to state that it must be a keyword).

One area where I think adding keyword args is outright wrong: Methods of built-in types or ABCs and that are overridable. E.g. consider the pop() method on dict. Since the argument name is currently undocumented, if someone subclasses dict and overrides this method, or if they create another mutable mapping class that tries to emulate dict using duck typing, it doesn't matter what the argument name is -- all the callers (expecting a dict, a dict subclass, or a dict-like duck) will be using positional arguments in the call. But if we were to document the argument names for pop(), and users started to use these, then most dict sublcasses and ducks would suddenly be broken (except if by luck they happened to pick the same name).

关于python - 请解释为什么这两个内置函数在传入关键字参数时表现不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10894135/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com