A modern Python approach with Python 3.5+ would be:
>>> import locale
>>> locale.setlocale(locale.LC_NUMERIC, "de_DE")
>>> f'{Decimal("5000.00"):n}'
'5.000,00'
>>> locale.setlocale(locale.LC_NUMERIC, "en_US")
'en_US'
>>> f'{Decimal("5000.00"):n}'
'5,000.00'
F-strings support advanced formatting. Hence, there is no need for extra f function. Babel for Python will give you a bit more convenience:
>>> from babel import numbers
>>> numbers.format_decimal(.2345, locale='en_US')
'0.234'
>>> numbers.format_decimal(.2345, locale='de_DE')
'0,234'
Answer from oz123 on Stack OverflowA modern Python approach with Python 3.5+ would be:
>>> import locale
>>> locale.setlocale(locale.LC_NUMERIC, "de_DE")
>>> f'{Decimal("5000.00"):n}'
'5.000,00'
>>> locale.setlocale(locale.LC_NUMERIC, "en_US")
'en_US'
>>> f'{Decimal("5000.00"):n}'
'5,000.00'
F-strings support advanced formatting. Hence, there is no need for extra f function. Babel for Python will give you a bit more convenience:
>>> from babel import numbers
>>> numbers.format_decimal(.2345, locale='en_US')
'0.234'
>>> numbers.format_decimal(.2345, locale='de_DE')
'0,234'
Reading through the source for the decimal module, Decimal.__format__ provides full PEP 3101 support, and all you have to do is select the correct presentation type. In this case, you want the :n type. According PEP 3101 spec, this :n has the following properties:
'n' - Number. This is the same as 'g', except that it uses the current locale setting to insert the appropriate number separator characters.
This is simpler than other answers, and avoids the float precision issue in my original answer (preserved below):
>>> import locale
>>> from decimal import Decimal
>>>
>>> def f(d):
... return '{0:n}'.format(d)
...
>>>
>>> locale.setlocale(locale.LC_ALL, 'en_us')
'en_us'
>>> print f(Decimal('5000.00'))
5,000.00
>>> print f(Decimal('1234567.000000'))
1,234,567.000000
>>> print f(Decimal('123456700000000.123'))
123,456,700,000,000.123
>>> locale.setlocale(locale.LC_ALL, 'no_no')
'no_no'
>>> print f(Decimal('5000.00'))
5.000,00
>>> print f(Decimal('1234567.000000'))
1.234.567,000000
>>> print f(Decimal('123456700000000.123'))
123.456.700.000.000,123
Original, wrong answer
You can just tell the format string to use as much precision as is included in the decimal itself and use the locale formatter:
def locale_format(d):
return locale.format('%%0.%df' % (-d.as_tuple().exponent), d, grouping=True)
Note that works if you've got a decimal which corresponds to a real number, but doesn't work correctly if the decimal is NaN or +Inf or something like that. If those are possibilities in your input, you'd need to account for them in the format method.
>>> locale.setlocale(locale.LC_ALL, 'en_US')
'en_US'
>>> locale_format(Decimal('1234567.000000'))
'1,234,567.000000'
>>> locale_format(Decimal('5000.00'))
'5,000.00'
>>> locale.setlocale(locale.LC_ALL, 'no_no')
'no_no'
>>> locale_format(Decimal('1234567.000000'))
'1.234.567,000000'
>>> locale_format(Decimal('5000.00'))
'5.000,00'
>>> locale_format(Decimal('NaN'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in locale_format
TypeError: bad operand type for unary -: 'str'
Python point formatting using {}.format and non-English locales
How to format a number with locale and specified number of significant decimals in python - Stack Overflow
Relatorio: How to locale-format a Python Decimal and preserve its precision?
locale - Format numbers as currency in Python - Stack Overflow
babel.numbers
In [22]: from babel.numbers import format_decimal
In [23]: format_decimal(12345, locale='de_DE')
Out[23]: u'12.345'
In [24]: format_decimal(1.2345, locale='sv_SE')
Out[24]: u'1,234'
Or in your case format_currency:
In [7]: from babel.numbers import format_currency
In [8]: print format_currency(1099.98, 'USD', locale='en_US')
$1,099.98
In [9]: print format_currency(1099.98, 'USD', locale='es_CO')
1.099,98 US$
In [10]: print format_currency(1099.98, 'EUR', locale='de_DE')
1.099,98 €
For reference (for those that are looking to format numbers similar to how you would format currency), you can use locale.format_string to format numbers
value = 123456789
import locale
locale.setlocale(locale.LC_ALL, 'de_DE')
print(locale.format_string('%.2f', value, True))
Would return
123.456.789,00