ローカライズ(地域ごとの通貨記号・桁区切り)を f文字列で扱う方法を、初心者でも実務で使えるようにやさしくまとめます。ポイント・短所・安全な実装例(locale と Babel)を両方お見せします。
ポイントまとめ
- f文字列自体は「埋め込み式を評価して文字列化する」機能。数値の見た目(桁区切り・小数桁など)は f文字列のフォーマット指定子でかなりできる。
例:f"{value:,.2f}"は英語圏でよく見る「3桁カンマ+小数2桁」。 - **ロケール依存の表現(小数の区切りが
.か,、通貨シンボルの位置など)**を正しくやるには、標準ライブラリのlocaleを使う方法と、より正確で便利な外部ライブラリBabel(推奨)を使う方法がある。 - 注意点:
locale.setlocale()は プロセス全体に影響(スレッド安全ではない)。サーバーアプリやマルチスレッドでは避けるか影響を把握して使う。Webアプリ等ではBabelのようなライブラリが安全で便利。
手軽な方法:f文字列+フォーマット(ロケール無視)
最も簡単。グローバルなロケールは無視して「常にカンマ区切り」「固定小数」を表示するパターン。
price = 1234567.89
print(f"{price:,.2f}") # 出力: 1,234,567.89
Python長所:簡単、依存なし。
短所:欧州の小数区切りが , の国では誤り。通貨記号の位置・空白・通貨単位のローカライズは自分で実装する必要あり。
標準ライブラリ locale を使う(小規模スクリプト向け)
locale を設定すると :n フォーマットや locale.format_string がロケールに従う出力を行えます。
import locale
from datetime import datetime
# 例:日本(Windowsでは "ja_JP" や "Japanese_Japan.932" などが必要)
locale.setlocale(locale.LC_ALL, "ja_JP.UTF-8") # Unix系で一般的
value = 1234567.89
# ロケールに依存した数値フォーマット('n' はロケール依存)
print(f"{value:n}") # 日本なら "1234567.89"(小数点は .)
# locale.format_string で桁区切りを明示
print(locale.format_string("%0.2f", value, grouping=True)) # "1,234,567.89"
# 通貨表示(locale によるが locale.currency は通貨記号を付ける)
print(locale.currency(value, grouping=True)) # 例: "¥1,234,567.89"(ロケール次第)
Python注意:
locale.setlocale()はプロセス全体に作用します(スレッドセーフでない)。Webサーバー等で使う際は注意。- Windows と Unix でロケール名が違うことがある(例:
"ja_JP.UTF-8"vs"Japanese_Japan.932")。環境ごとに試す必要あり。
実務での推奨:Babel を使う(ロケールごとに安全・確実)
Babel はロケールごとの通貨表示・桁区切り・小数・通貨記号配置を正しくやってくれるライブラリ。スレッド安全で、一回の呼び出しで任意のロケールに対してフォーマットできます。
インストール:
pip install Babel
使い方(例):
from babel.numbers import format_currency, format_decimal
value = 1234567.89
# 日本円(JPY)は小数を出さないことが多いので小数0にする例
print(format_currency(1234567, 'JPY', locale='ja_JP')) # '¥1,234,567'
# 米ドル($)英語(米国)
print(format_currency(value, 'USD', locale='en_US')) # '$1,234,567.89'
# ドイツ語(ドイツ): 小数区切りがカンマ、桁区切りがドット
print(format_currency(value, 'EUR', locale='de_DE')) # '1.234.567,89\xa0€'
# 純数値(ロケール依存の小数/桁区切り)
print(format_decimal(value, locale='de_DE')) # '1.234.567,89'
Python長所:
- ロケールごとのルールに忠実(通貨記号の位置、空白、単位の省略の仕方など)。
- スレッド安全で任意ロケールを指定可能(
setlocale不要)。 - 通貨通しの違い(JPY の小数有無など)にも配慮される。
短所:外部依存(ただし pip で簡単に入る)。
実例:ユーザーごとに異なるロケールでメール本文を作る(Babel と f文字列の組合せ)
from babel.numbers import format_currency
def order_email(user, amount, currency, locale):
money = format_currency(amount, currency, locale=locale)
return f"""{user}様
ご注文ありがとうございます。
合計金額: {money}
よろしくお願いします。
"""
print(order_email("田中", 122400, "JPY", "ja_JP"))
print(order_email("John", 122400.5, "USD", "en_US"))
print(order_email("Hans", 122400.5, "EUR", "de_DE"))
Python出力例(ロケールごとに適切に表示):
- 日本語:
¥122,400 - 英語 (US):
$122,400.50 - ドイツ語:
122.400,50 €(小数カンマ、通貨記号は末尾)
実装上の注意と落とし穴
- スレッド/プロセス全体への影響
locale.setlocale()はプロセス全体を変える → マルチスレッド環境や Web サーバーでは危険。Babel を使うと安全。
- ロケール名の違い
- Windows と Unix(Linux/macOS)で利用できるロケール名が異なる。テストが必要。
- 通貨の小数桁
- 通貨によっては小数を表示しない(JPY)/2桁(USD, EUR)。Babel はこの情報を正しく扱う。
- 表示と内部値は分ける
- 通貨の計算は整数(セント単位など)か Decimal 型で行い、表示だけロケールで整形するのが安全(浮動小数点の丸め誤差回避)。
- 例:
from decimal import Decimalを使う。
- サードパーティの信頼性
- Babel は広く使われているが、特殊要件があれば ICU(PyICU)等の採用検討も。
まとめ(選び方)
- 単純な用途/単一ロケール:
f"{value:,.2f}"で十分。 - スクリプトで環境に応じてロケールを変えて良い(かつ単一スレッド):
localeが使える。 - 多言語対応のアプリ・Web サービス:Babel を強く推奨。ロケールごとの表示ルールを安全に、正確にやってくれます。


