[Python] gettextモジュールの使い方 – アプリの国際化対応
Pythonのgettext
モジュールは、アプリケーションの国際化(i18n)をサポートするために使用されます。
gettext
を使うことで、アプリケーションのメッセージを複数の言語に翻訳できます。
基本的な使い方は、まず翻訳対象の文字列を_("メッセージ")
のようにマークします。
次に、xgettext
コマンドで翻訳ファイル(.poファイル)を生成し、翻訳を追加します。
最後に、gettext.translation()
で翻訳をロードし、install()メソッド
でデフォルトの翻訳関数を設定します。
gettextモジュールとは
gettext
モジュールは、Pythonにおける国際化(i18n)および地域化(l10n)をサポートするためのライブラリです。
このモジュールを使用することで、アプリケーションのユーザーインターフェースを複数の言語に対応させることができます。
具体的には、アプリケーション内の文字列を翻訳するための機能を提供し、ユーザーの言語設定に基づいて適切な翻訳を選択することが可能です。
gettext
は、翻訳対象の文字列を特定の形式でマークし、翻訳ファイル(.poファイル)を作成することで機能します。
これにより、開発者はアプリケーションのコードを変更することなく、翻訳を追加・更新することができます。
国際化対応を行うことで、より多くのユーザーにアプローチできるようになり、アプリケーションの利用範囲を広げることができます。
gettextモジュールのインストールと設定
gettextモジュールのインストール方法
gettext
モジュールは、Pythonの標準ライブラリに含まれているため、特別なインストールは不要です。
Pythonがインストールされていれば、すぐに使用することができます。
以下のコマンドでPythonがインストールされているか確認できます。
python --version
言語ファイル(.poファイル)の作成
言語ファイルは、翻訳対象の文字列を管理するためのファイルです。
.po
ファイルは、テキスト形式で翻訳を記述します。
以下の手順で.po
ファイルを作成します。
- プロジェクトのルートディレクトリに
locale
というディレクトリを作成します。 locale
ディレクトリ内に、言語コード(例:ja
)のサブディレクトリを作成します。- その中に
LC_MESSAGES
というサブディレクトリを作成します。 - 最後に、翻訳対象の文字列を記述した
.po
ファイルを作成します。
/locale
└── ja
└── LC_MESSAGES
└── messages.po
言語ファイルのコンパイル(.moファイルの生成)
.po
ファイルを作成したら、次にそれをコンパイルして.mo
ファイルを生成します。
.mo
ファイルは、実行時に使用されるバイナリ形式の翻訳ファイルです。
以下のコマンドを使用してコンパイルします。
msgfmt locale/ja/LC_MESSAGES/messages.po -o locale/ja/LC_MESSAGES/messages.mo
このコマンドを実行することで、messages.po
ファイルがコンパイルされ、messages.mo
ファイルが生成されます。
これで、アプリケーションで翻訳を使用する準備が整いました。
gettextの基本的な使い方
翻訳対象の文字列をマークする方法
翻訳対象の文字列をマークするためには、gettext
モジュールのgettext()関数
を使用します。
通常、翻訳対象の文字列は、_()
というエイリアスを使ってマークします。
以下のように記述します。
import gettext
# 翻訳対象の文字列をマーク
_ = gettext.gettext
print(_("こんにちは"))
このコードでは、"こんにちは"
という文字列が翻訳対象としてマークされています。
gettext.translation()の使い方
gettext.translation()関数
は、特定の言語の翻訳ファイルをロードするために使用します。
この関数は、言語コード、ドメイン名、検索パスを引数に取ります。
以下はその使用例です。
import gettext
# 日本語の翻訳ファイルをロード
translation = gettext.translation('messages', localedir='locale', languages=['ja'])
translation.install()
# 翻訳された文字列を表示
print(_("こんにちは"))
このコードでは、messages
というドメイン名の日本語翻訳ファイルをロードし、翻訳された文字列を表示します。
install()メソッドでデフォルトの翻訳関数を設定する
install()メソッド
を使用すると、gettext
のデフォルトの翻訳関数を設定できます。
これにより、_()
を使って簡単に翻訳を呼び出すことができます。
以下のように記述します。
import gettext
# 日本語の翻訳ファイルをロード
translation = gettext.translation('messages', localedir='locale', languages=['ja'])
translation.install()
# デフォルトの翻訳関数を設定
_ = translation.gettext
# 翻訳された文字列を表示
print(_("こんにちは"))
gettext()とngettext()の違い
gettext()
は単数形の翻訳を取得するための関数ですが、ngettext()
は複数形の翻訳を取得するために使用します。
ngettext()
は、数値を引数に取り、単数形と複数形の翻訳を選択します。
以下はその使用例です。
import gettext
# 日本語の翻訳ファイルをロード
translation = gettext.translation('messages', localedir='locale', languages=['ja'])
translation.install()
# 単数形と複数形の翻訳を表示
print(ngettext("1件のメッセージ", "%d件のメッセージ", 1) % 1) # 1件のメッセージ
print(ngettext("1件のメッセージ", "%d件のメッセージ", 2) % 2) # 2件のメッセージ
翻訳ファイルのロードと使用
翻訳ファイルをロードする際は、gettext.translation()
を使用し、必要な言語の翻訳ファイルを指定します。
ロードした翻訳ファイルを使用することで、アプリケーション内の文字列を簡単に翻訳できます。
以下のコードは、翻訳ファイルをロードし、翻訳された文字列を表示する例です。
import gettext
# 日本語の翻訳ファイルをロード
translation = gettext.translation('messages', localedir='locale', languages=['ja'])
translation.install()
# 翻訳された文字列を表示
print(_("こんにちは"))
このようにして、アプリケーション内で翻訳を簡単に利用することができます。
実際の翻訳ファイルの作成手順
xgettextコマンドで.poファイルを生成する
xgettext
コマンドは、ソースコードから翻訳対象の文字列を抽出し、.po
ファイルを生成するために使用します。
以下のコマンドを実行することで、指定したPythonファイルから翻訳対象の文字列を抽出し、messages.po
ファイルを生成します。
xgettext -d messages -o locale/ja/LC_MESSAGES/messages.po your_script.py
ここで、your_script.py
は翻訳対象のPythonファイルの名前です。
このコマンドを実行すると、locale/ja/LC_MESSAGES/messages.po
というファイルが生成されます。
.poファイルの編集方法
生成された.po
ファイルはテキストエディタで開くことができ、翻訳を追加・編集することができます。
.po
ファイルの基本的な構造は以下のようになっています。
msgid "原文の文字列"
msgstr "翻訳された文字列"
例えば、以下のように編集します。
msgid "Hello"
msgstr "こんにちは"
msgid "Goodbye"
msgstr "さようなら"
このように、msgid
に原文の文字列、msgstr
に翻訳された文字列を記述します。
すべての翻訳対象の文字列に対してこの形式で翻訳を追加します。
msgfmtコマンドで.moファイルを生成する
編集が完了したら、msgfmt
コマンドを使用して.po
ファイルをコンパイルし、.mo
ファイルを生成します。
以下のコマンドを実行します。
msgfmt locale/ja/LC_MESSAGES/messages.po -o locale/ja/LC_MESSAGES/messages.mo
このコマンドを実行することで、messages.po
ファイルがコンパイルされ、messages.mo
ファイルが生成されます。
.mo
ファイルは、実行時に使用されるバイナリ形式の翻訳ファイルです。
これで、アプリケーションで翻訳を使用する準備が整いました。
複数言語対応の実装例
単一言語の翻訳例
単一言語の翻訳を実装するには、まず対象の言語の翻訳ファイルを用意し、gettext
モジュールを使用して翻訳を行います。
以下は、日本語の翻訳を行う例です。
import gettext
# 日本語の翻訳ファイルをロード
translation = gettext.translation('messages', localedir='locale', languages=['ja'])
translation.install()
# 翻訳された文字列を表示
print(_("こんにちは")) # 出力: こんにちは
このコードでは、日本語の翻訳ファイルをロードし、翻訳された文字列を表示しています。
複数言語の切り替え方法
複数言語に対応するためには、ユーザーが選択した言語に基づいて翻訳ファイルをロードする必要があります。
以下は、英語と日本語の切り替えを行う例です。
import gettext
def set_language(lang):
translation = gettext.translation('messages', localedir='locale', languages=[lang])
translation.install()
# ユーザーが選択した言語を設定
set_language('ja') # 日本語を選択
print(_("こんにちは")) # 出力: こんにちは
set_language('en') # 英語を選択
print(_("こんにちは")) # 出力: Hello
このコードでは、set_language関数
を使用して、選択された言語に応じて翻訳ファイルを切り替えています。
ユーザーの言語設定に基づく自動翻訳
ユーザーの言語設定に基づいて自動的に翻訳を行うには、環境変数や設定ファイルから言語を取得し、その言語に応じて翻訳ファイルをロードします。
以下はその例です。
import gettext
import os
# 環境変数から言語を取得
user_language = os.getenv('LANGUAGE', 'en') # デフォルトは英語
# 言語に応じて翻訳ファイルをロード
translation = gettext.translation('messages', localedir='locale', languages=[user_language])
translation.install()
# 翻訳された文字列を表示
print(_("こんにちは")) # ユーザーの言語設定に応じた出力
このコードでは、環境変数LANGUAGE
からユーザーの言語設定を取得し、その言語に基づいて翻訳を行っています。
翻訳が見つからない場合のデフォルト動作
翻訳が見つからない場合、デフォルトの動作を設定することができます。
gettext
モジュールでは、翻訳が見つからない場合に原文をそのまま表示することが一般的です。
以下はその実装例です。
import gettext
# 日本語の翻訳ファイルをロード
translation = gettext.translation('messages', localedir='locale', languages=['ja'], fallback=True)
translation.install()
# 翻訳が見つからない場合の動作
print(_("こんにちは")) # 出力: こんにちは
print(_("さようなら")) # 出力: さようなら(翻訳が見つからない場合は原文が表示される)
print(_("未翻訳の文字列")) # 出力: 未翻訳の文字列(翻訳が見つからない場合は原文が表示される)
このコードでは、fallback=True
を指定することで、翻訳が見つからない場合に原文を表示するように設定しています。
これにより、ユーザーは翻訳がない場合でも内容を理解することができます。
gettextを使ったアプリケーションの国際化
Webアプリケーションでのgettextの利用
Webアプリケーションにおいてgettext
を利用することで、ユーザーインターフェースを多言語対応にすることができます。
例えば、FlaskやDjangoなどのWebフレームワークと組み合わせて使用することが一般的です。
以下はFlaskを使用した例です。
from flask import Flask, request, render_template
import gettext
app = Flask(__name__)
# 言語設定に基づいて翻訳をロードする関数
def set_language(lang):
translation = gettext.translation('messages', localedir='locale', languages=[lang])
translation.install()
return translation.gettext
@app.route('/')
def index():
lang = request.args.get('lang', 'en') # URLパラメータから言語を取得
_ = set_language(lang) # 翻訳関数を設定
return render_template('index.html', greeting=_("こんにちは"))
if __name__ == '__main__':
app.run()
このコードでは、URLパラメータから言語を取得し、対応する翻訳を表示しています。
これにより、ユーザーは簡単に言語を切り替えることができます。
デスクトップアプリケーションでのgettextの利用
デスクトップアプリケーションでもgettext
を利用して国際化を行うことができます。
例えば、Tkinterを使用したGUIアプリケーションでの実装例は以下の通りです。
import tkinter as tk
import gettext
def set_language(lang):
translation = gettext.translation('messages', localedir='locale', languages=[lang])
translation.install()
return translation.gettext
def greet():
lang = 'ja' # 日本語を選択
_ = set_language(lang)
label.config(text=_("こんにちは"))
root = tk.Tk()
label = tk.Label(root, text="")
label.pack()
greet_button = tk.Button(root, text="挨拶", command=greet)
greet_button.pack()
root.mainloop()
このコードでは、ボタンをクリックすると日本語の挨拶が表示されるシンプルなGUIアプリケーションを作成しています。
コマンドラインツールでのgettextの利用
コマンドラインツールでもgettext
を利用して国際化を行うことができます。
以下は、コマンドライン引数に基づいて言語を切り替える例です。
import argparse
import gettext
def set_language(lang):
translation = gettext.translation('messages', localedir='locale', languages=[lang])
translation.install()
return translation.gettext
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='国際化対応のコマンドラインツール')
parser.add_argument('--lang', type=str, default='en', help='言語コードを指定 (例: ja, en)')
args = parser.parse_args()
_ = set_language(args.lang) # 言語を設定
print(_("こんにちは")) # 翻訳された文字列を表示
このコードでは、コマンドライン引数で指定された言語に基づいて翻訳を行い、挨拶を表示します。
これにより、ユーザーはコマンドラインから簡単に言語を選択できます。
gettextの応用例
複数言語の動的ロード
複数言語の動的ロードを実現するためには、ユーザーの選択に応じて翻訳ファイルをロードする仕組みを作ります。
以下は、ユーザーが選択した言語に基づいて翻訳を動的に切り替える例です。
import gettext
def load_translation(lang):
translation = gettext.translation('messages', localedir='locale', languages=[lang], fallback=True)
translation.install()
return translation.gettext
# ユーザーが選択した言語を取得
selected_language = 'fr' # 例: フランス語
_ = load_translation(selected_language)
print(_("こんにちは")) # フランス語の翻訳が表示される
このコードでは、load_translation関数
を使用して、選択された言語の翻訳ファイルを動的にロードしています。
翻訳メモリ(TM)との連携
翻訳メモリ(TM)を使用することで、過去の翻訳を再利用し、一貫性のある翻訳を提供することができます。
gettext
とTMを連携させるためには、TMのデータベースから翻訳を取得し、gettext
の翻訳関数に渡すことができます。
以下はその例です。
import gettext
# TMから翻訳を取得する関数
def get_translation_from_tm(original_text):
# ここでTMデータベースから翻訳を取得するロジックを実装
return "翻訳されたテキスト" # 仮の翻訳
def translate(text):
translation = get_translation_from_tm(text)
if translation:
return translation
else:
return text # 翻訳が見つからない場合は原文を返す
# 使用例
print(translate("Hello")) # TMからの翻訳が表示される
このコードでは、TMから翻訳を取得する関数を定義し、翻訳が見つからない場合は原文を返すようにしています。
翻訳のキャッシュ機能の実装
翻訳のキャッシュ機能を実装することで、同じ翻訳を何度も取得する際のパフォーマンスを向上させることができます。
以下は、翻訳結果をキャッシュする例です。
import gettext
translation_cache = {}
def get_translation(text, lang):
if (text, lang) in translation_cache:
return translation_cache[(text, lang)]
translation = gettext.translation('messages', localedir='locale', languages=[lang], fallback=True)
translation.install()
translated_text = translation.gettext(text)
# キャッシュに保存
translation_cache[(text, lang)] = translated_text
return translated_text
# 使用例
print(get_translation("こんにちは", "ja")) # キャッシュに保存される
print(get_translation("こんにちは", "ja")) # キャッシュから取得
このコードでは、翻訳結果をキャッシュに保存し、同じ翻訳を再度要求された場合にはキャッシュから取得するようにしています。
翻訳ファイルの自動更新スクリプト
翻訳ファイルを自動的に更新するスクリプトを作成することで、翻訳作業を効率化できます。
以下は、xgettext
を使用して翻訳ファイルを自動更新するスクリプトの例です。
import os
import subprocess
def update_translation_files():
# プロジェクトのソースコードから.poファイルを生成
subprocess.run(['xgettext', '-d', 'messages', '-o', 'locale/ja/LC_MESSAGES/messages.po', 'your_script.py'])
# .poファイルをコンパイルして.moファイルを生成
subprocess.run(['msgfmt', 'locale/ja/LC_MESSAGES/messages.po', '-o', 'locale/ja/LC_MESSAGES/messages.mo'])
# スクリプトを実行して翻訳ファイルを更新
update_translation_files()
このスクリプトでは、xgettext
を使用してソースコードから翻訳対象の文字列を抽出し、.po
ファイルを生成した後、msgfmt
を使用して.mo
ファイルを生成しています。
これにより、翻訳ファイルの更新作業を自動化できます。
まとめ
この記事では、Pythonのgettext
モジュールを使用したアプリケーションの国際化対応について詳しく解説しました。
具体的には、gettext
の基本的な使い方から、実際の翻訳ファイルの作成手順、複数言語対応の実装例、さらには応用例に至るまで、幅広く取り上げました。
これを機に、実際のプロジェクトにgettext
を活用し、ユーザーにとって使いやすい多言語対応のアプリケーションを作成してみてはいかがでしょうか。