从3.5中的floatobjects.c中的float_round源代码:
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,因此在3.4中导致RoundError(1.0,None)的TypeError.
在3.4和3.5中,longobject.c中的long_round中没有检查o_ndigits == Py_None,因此在3.4和3.5中都引发了round(1,None)的TypeError
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