为什么在 ndigits=None 上对整数而不是浮点数进行轮加?

Why does round raise on ndigits=None for integers but not for floats?

ndigits 明确设置为 None 时,为什么 round() 对 int 和 float 的行为不同?

Python 3.5.1 中的控制台测试:

>>> round(1, None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object cannot be interpreted as an integer
>>> round(1.0, None)
1

更新:

我将此报告为错误 (Issue #27936),该错误已修复并关闭。 @PadraicCunningham 和@CraigBurgler 是正确的。

此修复包含在以下最终版本中:

来自 float_round in floatobjects.c in 3.5 的源代码:

float_round(PyObject *v, PyObject *args)
    ... 
    if (!PyArg_ParseTuple(args, "|O", &o_ndigits))
        return NULL;
    ...
    if (o_ndigits == NULL || o_ndigits == Py_None) {
        /* single-argument round or with None ndigits:
         * round to nearest integer */
        ...

|| o_ndigits == Py_None 位显式捕获 ndigits=None 参数并将其丢弃,将对 round 的调用视为单参数调用。

3.4 中,此代码如下所示:

float_round(PyObject *v, PyObject *args)
    ... 
    if (!PyArg_ParseTuple(args, "|O", &o_ndigits))
        return NULL;
    ...
    if (o_ndigits == NULL) {
            /* single-argument round: round to nearest integer */
    ...

没有 || o_ndigits == Py_None 测试,因此 ndgits=None 论点落空并被视为 int,从而导致 TypeErrorround(1.0, None)3.4.

long_round in longobject.c in 3.43.5 都没有检查 o_ndigits == Py_None,因此引发了 TypeError round(1, None) 3.43.5

                treat ndigits=None as      resolve
Version/Type    single-argument call    round(n, None) 
 ----------       ---------------        -----------
  3.4/float              No               TypeError
  3.4/long               No               TypeError
  3.5/float              Yes               round(n)
  3.5/long               No               TypeError