Python localeとは?数値・通貨を地域の書式で表示する方法

localeは、数値や通貨を国・地域の書式で表示する標準ライブラリです。

桁区切りのカンマ、小数点のピリオド、通貨記号は国によって違います。localeはその差を吸収します。


何も設定しないと Cロケール

import locale

print(locale.getlocale(locale.LC_NUMERIC))
print(f"{1234567.891:n}")

実行結果:

(None, None)
1.23457e+06

書式指定の n は、何も設定しないと指数表記になります。これを知らずに使うと数値が読めない形で出てしまいます。


ロケールを設定する

for name in ("ja_JP.UTF-8", "en_US.UTF-8"):
    locale.setlocale(locale.LC_ALL, name)
    print(name, locale.getlocale(locale.LC_NUMERIC),
          locale.format_string("%d", 1234567, grouping=True))

実行結果:

ja_JP.UTF-8 ('ja_JP', 'UTF-8') 1,234,567
en_US.UTF-8 ('en_US', 'UTF-8') 1,234,567

grouping=Trueで桁区切りが入ります。日本語環境と英語環境はどちらも3桁区切りなので同じ結果です。


通貨記号

locale.setlocale(locale.LC_ALL, "ja_JP.UTF-8")
print(locale.currency(1234567, grouping=True))

conv = locale.localeconv()
print({k: conv[k] for k in ("decimal_point", "thousands_sep", "currency_symbol")})

実行結果:

¥1,234,567
{'decimal_point': '.', 'thousands_sep': ',', 'currency_symbol': '¥'}

localeconv()を見ればその環境で使われる記号が全部分かります。自前で書式を組むときの参照先になります。


存在しないロケールはエラー

try:
    locale.setlocale(locale.LC_ALL, "xx_XX.UTF-8")
except locale.Error as e:
    print("locale.Error ->", e)

実行結果:

locale.Error -> unsupported locale setting

使えるロケールはOSに入っているものだけです。Linuxのコンテナにはja_JP.UTF-8が入っていないことが多く、手元では動くのに本番で落ちる原因になります。

そのためロケール設定は必ず例外を捕まえて、失敗しても処理が続くように書きます。

import locale

for cand in ("ja_JP.UTF-8", "ja_JP.utf8", "C.UTF-8", ""):
    try:
        locale.setlocale(locale.LC_ALL, cand)
        break
    except locale.Error:
        continue

桁区切りだけなら locale は不要

実のところ、桁区切りを入れたいだけなら書式指定の方が確実です。

n = 1234567
print(f"{n:,}")
print(f"{n:,.2f}")

実行結果:

1,234,567
1,234,567.00

,はロケールに関係なくカンマ区切りになります。環境差で壊れないので、日本向けの表示ならこちらをおすすめします。


プロセス全体に影響する

setlocale() はプログラム全体の設定を書き換えます。スレッドごとに別のロケールにはできません。ライブラリの中で勝手に呼ぶと、呼び出し側の表示まで変わってしまいます。

多言語のWebアプリのようにリクエストごとに言語が違う場面では locale は向きません。文言の切り替えはPython gettextとは?メッセージを多言語化する方法、数値の書式は書式指定で作るのが安全です。


まとめ

  • 何も設定しないとCロケール。:nは指数表記になる
  • setlocale()はOSにそのロケールが無いとlocale.Error
  • プロセス全体に効くのでライブラリ内で呼ばない
  • 桁区切りだけならf'{n:,}'で十分

関連記事

あわせて読むと理解が深まります。

プログラミング学習に興味がある方は、まずは無料体験会へ

無料体験会・お申し込みはこちら