I need to output decimal numbers in a price forma开发者_如何学编程t,
i.e.
10 = 10.00 11.1 = 11.10
How can I achieve this using decimal.Decimal class ?
pad_zero(Decimal('10.0'))
>>>Decimal('10.00')
*EDIT:*format method does not fit my need because I need to pass it on as decimal, I understand though, that i can convert it back to afterwards, but such to-and-fro seems somewhat unpythonic.
try this :
Decimal('10.0').quantize(Decimal('1.00'))
For currency calculations, I prefer this.
>>> penny=Decimal('0.01')
>>> Decimal('10').quantize(penny)
Decimal('10.00')
It's wordy but explicit.
For currency formatting, I use format()
.
There's a good example of how to format Decimal objects as a "money formatted string" in the Python documentation for the decimal module.
I'm a little surprised at how awkward it is -- usually formatting in Python is fairly straightforward.
I would follow the moneyfmt
recipe in the Python Decimal documentation Recipes section.
This recipe creates a function that takes a decimal value and returns a string formatted as a currency.
>>> d = Decimal('10.0')
>>> moneyfmt(d, curr='$')
'$10.00'
Below is the actual code, copied sans examples from the Decimal Recipe documentation:
def moneyfmt(value, places=2, curr='', sep=',', dp='.',
pos='', neg='-', trailneg=''):
"""Convert Decimal to a money formatted string.
places: required number of places after the decimal point
curr: optional currency symbol before the sign (may be blank)
sep: optional grouping separator (comma, period, space, or blank)
dp: decimal point indicator (comma or period)
only specify as blank when places is zero
pos: optional sign for positive numbers: '+', space or blank
neg: optional sign for negative numbers: '-', '(', space or blank
trailneg:optional trailing minus indicator: '-', ')', space or blank
"""
q = Decimal(10) ** -places # 2 places --> '0.01'
sign, digits, exp = value.quantize(q).as_tuple()
result = []
digits = map(str, digits)
build, next = result.append, digits.pop
if sign:
build(trailneg)
for i in range(places):
build(next() if digits else '0')
build(dp)
if not digits:
build('0')
i = 0
while digits:
build(next())
i += 1
if i == 3 and digits:
i = 0
build(sep)
build(curr)
build(neg if sign else pos)
return ''.join(reversed(result))
It should be quite simple like this (if you don't use decimal.Decimal class as suggested by S. Lott) :
>>> decimal_fmt = "{:.2f}"
>>> x = 10
>>> print(decimal_fmt.format(x))
10.00
>>> x = 11.1
>>> print(decimal_fmt.format(x))
11.10
Set the precision for your context before you create your instance:
>>> getcontext().prec = 2
Use locale currency
. It works flawlessly with the Decimal class.
import locale
locale.setlocale(locale.LC_ALL, '') # this sets locale to the current Operating System value
print(locale.currency(Decimal('1346896.67544'), grouping=True, symbol=True))
will output in my Windows 10 configured to Brazilian Portuguese:
R$ 1.346.896,68
It is somewhat verbose, so if you will use it a lot, maybe it is better to predefine some parameters and have a shorter name and use it inside a f-string:
fmt = lambda x: locale.currency(x, grouping=True, symbol=True)
print(f"Value: {fmt(1346896.67444)}"
It works with Decimal
and float
. You can configure to symbol to False
if it isn't necessary.
Instead of using Decimal('10.0')
you could use float('10.0')
which will produce the effect you require.
Edit: Realised that you were looking to represent it with 2 decimal places. In this case, there's a good example in the Python docs for converting a Decimal()
object to money: http://docs.python.org/library/decimal.html#recipes
精彩评论