2016-09-01 2 views
4

Почему round() ведут себя разные для int и float, когда ndigits явно установлен на None?Почему round raise на ndigits = None для целых чисел, но не для 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 

Update:

Я об этом как об ошибке (Issue #27936), которая была закреплена и закрыта. @PadraicCunningham и @CraigBurgler были правильными.

исправление было включено в следующие заключительные релизы:

+0

Я получаю тот же 'TypeError' в Python 3.4 для' круглый (1.0, None) ' –

+0

Я думаю, потому что Integer не нужно округлять. – giaosudau

+2

@giaosudau: вы можете использовать круглые целые числа для округления до ближайшего 10. 'round (7, -1) => 10' – Jonatan

ответ

3

Из исходного кода для float_round в floatobjects.c в 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, тем самым вызывая TypeError для round(1.0, None) в 3.4.

Там нет проверки на o_ndigits == Py_None в long_round в longobject.c как в 3.4 и 3.5, тем самым повышая TypeError для round(1, None) в обоих 3.4 и 3.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 
+1

Мы уже знали, что это в исходном коде, OP хочет знать, что является основной причиной? – Kasramvd

+2

Там * есть * нет веской причины для ошибки консистенции –

+2

У меня нет подсказки, почему этот ответ проголосовали. Это как раз * почему *, описанный и показанный с помощью исходного кода Python. Возможно, Python не следует писать так. Если да, отправьте некоторые запросы на изменение. Но поэтому 'round()' ведет себя так, как есть. –

 Смежные вопросы

  • Нет связанных вопросов^_^