阅读decimal 模块的源代码,Decimal.__format__ 提供完整的PEP 3101 支持,您所要做的就是选择正确的演示类型。在这种情况下,您需要 :n 类型。根据 PEP 3101 规范,:n 具有以下属性:
'n' - 数字。这与 'g' 相同,只是它使用
当前区域设置以插入适当的
数字分隔符。
这比其他答案更简单,并且避免了我原始答案中的浮点精度问题(保留在下面):
>>> 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
原来的错误答案
您可以告诉格式字符串使用与小数本身一样多的精度,并使用语言环境格式化程序:
def locale_format(d):
return locale.format('%%0.%df' % (-d.as_tuple().exponent), d, grouping=True)
请注意,如果您有一个与实数相对应的小数,则该方法有效,但如果小数为 NaN 或 +Inf 或类似的值,则无法正常工作。如果您的输入中有这些可能性,您需要在格式方法中考虑它们。
>>> 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'