在 Python 中将数字格式化为货币

Format numbers as currency in Python

我从 Currency formatting in Python, use the locale 模块中学习如何将数字格式化为货币。例如,

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import locale

value = 123456789

l = locale.setlocale(locale.LC_ALL, '')     # LC_CTYPE=en_US.UTF-8;LC_NUMERIC=fr_FR.UTF-8;LC_TIME=fr_FR.UTF-8;LC_COLLATE=en_US.UTF-8;LC_MONETARY=fr_FR.UTF-8;LC_MESSAGES=en_US.UTF-8;LC_PAPER=fr_FR.UTF-8;LC_NAME=fr_FR.UTF-8;LC_ADDRESS=fr_FR.UTF-8;LC_TELEPHONE=fr_FR.UTF-8;LC_MEASUREMENT=fr_FR.UTF-8;LC_IDENTIFICATION=fr_FR.UTF-8
s = locale.currency(value, grouping=True)   # 123 456 789,00 €

locale.setlocale(locale.LC_ALL, 'en_US.utf-8') 
s = locale.currency(value, grouping=True)   # 3,456,789.00

locale.setlocale(locale.LC_ALL, 'en_US')    # WHY? locale.Error: unsupported locale setting
s = locale.currency(value, grouping=True)

我想将数字格式化为其他货币,比如 de_DE。我遇到了问题 locale.Error: unsupported locale setting,因为语言环境 de_DE 不在 locale -a 的列表中。

locale.setlocale(locale.LC_ALL, 'de_DE')        # locale.Error: unsupported locale setting
s = locale.currency(value, grouping=True)

一种解决方案是将此语言环境添加到我的机器中。有没有更好的方法?

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'

或者你的情况 format_currency:

In [7]: from babel.numbers import format_currency

In [8]: print format_currency(1099.98, 'USD', locale='en_US')
,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 €

供参考(对于那些希望像格式化货币一样格式化数字的人),您可以使用 locale.format_string 格式化数字

value = 123456789

import locale
locale.setlocale(locale.LC_ALL, 'de_DE') 
print(locale.format_string('%.2f', value, True))

会return

123.456.789,00

我知道有两种解决方法:

通天塔

Babel 是最佳解决方案,因为您可以选择任何货币,而不管区域设置。

缺点是它的文档很少。要了解所有选项,您必须阅读 Babel source code 以了解您要使用的功能

安装 Babel:

$ pip install Babel

使用方法:

import babel.numbers

amount = 123456789.123

print(babel.numbers.format_currency(amount, 'EUR', locale='fr_CA'))
# 123 456 789,12 €

print(babel.numbers.format_currency(amount, 'EUR', locale='en_CA'))
# €123,456,789.12

print(babel.numbers.format_currency(amount, '', locale='en_CA'))
# 123,456,789.12

localize.currency()

locale.currency() 的一个限制是它假设货币与区域设置相匹配。例如 en_US => $/USDfr_FR => €/EUR 因此,如果显示的货币与区域设置不匹配,您可能希望使用 String.replace() 方法替换货币符号。

根据区域设置,例如en_USen_GBfr_FRfr_CA,它会知道:

  • 使用哪个小数分隔符(例如 100.00100,00
  • 使用哪个千位分隔符(例如 1,0001.000
  • 使用哪个货币符号(例如 0€100USD 100EUR 100
  • 在哪里放置货币符号(例如 0100 $
import locale

locale.setlocale(locale.LC_ALL, 'fr_FR')

amount = 123456789.123
grouping = True  # thousands separator

# '123.456.789,12 Eu'
locale.currency(amount, symbol=True, grouping=True, international=False)

# '123.456.789,12 EUR'
locale.currency(amount, symbol=True, grouping=True, international=False)

# '123.456,789'
locale.currency(amount, symbol=False, grouping=True)

# '123456,789'
locale.currency(amount, symbol=False, grouping=True)

可选参数如下

# which currency symbol to use, and where to place it
symbol=True and international=True # => 'USD 100.00'
symbol=True and international=False # => '0.00'
symbol=False # => '100.00'

# thousands separator
grouping = True # => '1000.00'
grouping = False # => '1,000.00'