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:,}'で十分
関連記事
あわせて読むと理解が深まります。




