Обратите внимание, что при вызове round
вы получаете значение с плавающей точкой как результат, не Decimal
. round
принуждает значение к поплавку, а затем округляет его в соответствии с правилами округления поплавка.
Если вы используете опциональный параметр ndigits
, когда вы вызываете round()
, вы вернетесь к десятичному результату, и в этом случае он будет действовать так, как вы ожидали.
Python 3.4.1 (default, Sep 24 2015, 20:41:10)
[GCC 4.9.2 20150212 (Red Hat 4.9.2-6)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import decimal
>>> context = decimal.getcontext()
>>> context.rounding = decimal.ROUND_HALF_UP
>>> round(decimal.Decimal('2.5'), 0)
Decimal('3')
я не нашел, где это документально подтверждено, что round(someDecimal)
возвращает Int, но round(someDecimal, ndigits)
возвращает десятичное, но это, кажется, что происходит в Python 3.3 и более поздних. В Python 2.7 вы всегда возвращаете float при вызове round()
, но Python 3.3 улучшил интеграцию Decimal
с встроенными Python.
Как отмечено в комментарии, round()
делегатов Decimal.__round__()
и что на самом деле показывает такое же поведение:
>>> Decimal('2.5').__round__()
2
>>> Decimal('2.5').__round__(0)
Decimal('3')
Хочу отметить, что документация Fraction
говорит:
__round__()
__round__(ndigits)
The first version returns the nearest int to self, rounding half to even.
The second version rounds self to the nearest multiple of Fraction(1, 10**ndigits)
(logically, if ndigits is negative), again rounding half toward even.
This method can also be accessed through the round() function.
Таким образом, поведение согласуется в том, что без аргумента он изменяет тип результата и округляет половину до четного, однако кажется, что Decimal
не документирует поведение своего метода __round__
,
Редактировать, чтобы отметить, как говорит Барри Херли в комментариях, round()
документируется как возвращающий int
, если вызывается без необязательных аргументов и «значение с плавающей запятой», если предоставляется дополнительный аргумент. https://docs.python.org/3/library/functions.html#round
Спасибо @ Duncan за объяснение, всегда полезно попытаться понять эти вещи. Кажется очень странным, что возвращается другой _type_ в зависимости от того, укажите ли вы ndigits или нет. –
В качестве дополнения, python 3 docs заявляют, что он делегирует 'number .__ round __ (ndigits)', а утилиты 'decimal' реализует свой собственный метод' __round__' –
@Dunca, он выглядит как int, а не float: «Если ndigits опущен или None, он возвращает ближайшее целое к его вводу». https://docs.python.org/3/library/functions.html#round –