# study-i18n-python **Repository Path**: Silfra/study-i18n-python ## Basic Information - **Project Name**: study-i18n-python - **Description**: 学习 python 程序中的国际化 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-01-22 - **Last Updated**: 2025-01-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 国际化支持 默认国际化系统(如 `gettext`)的惯例是将英文作为默认语言( `msgid` ),其他语言作为翻译。 根据 `requirements.txt` 文件,使用 python 3.12 建立虚拟环境(也可以使用其它 python 版本,对版本没有必然要求,但最好是 3 版本)。 ## 生成需要国际化的程序文件 这里使用 `app.py` 作为需要国际化的程序代码文件,内容如下: `app.py` : ```python # 引入 gettext 模块,用于实现多语言支持 import gettext # 定义主函数 def main(): # 提示用户选择语言 print("Please select a language:") print("1. English") print("2. 中文 (Chinese)") choice = input("Enter 1 or 2 to select a language: ").strip() # 根据用户输入选择语言 if choice == "2": language = "zh" # 用户选择中文 else: language = "en" # 默认语言是英文 # 加载翻译文件 # domain: 翻译文件的名字,默认是 "messages" # localedir: 翻译文件所在目录,比如 "locale" # languages: 选择的语言代码,比如 "en" 或 "zh" # 加载翻译文件 translator = gettext.translation( domain="messages", # 翻译文件的名字 localedir="locale", # 翻译文件存放的目录 languages=[language], # 用户选择的语言 fallback=True, # 如果没有找到翻译文件,回退到默认语言 ) translator.install() # 安装翻译工具,让程序支持 _() 方法 # 使用 _() 方法输出翻译的内容 print(_("Hello, world!")) # 翻译 "Hello, world!" print( _("This is a multilingual application.") ) # 翻译 "This is a multilingual application." print(_("Goodbye!")) # 翻译 "Goodbye!" # 只有当脚本直接运行时,才会执行 main 函数 if __name__ == "__main__": main() ``` 其中, `gettext.translation` 函数中的一些参数解释如下: - `domain="messages"` 表示寻找 `messages` 文件,默认扩展名为 `mo` ,即寻找 `messages.mo` 文件。 - `localedir="locale"` 表示从 `locale` 文件夹下进行寻找 > `locale` 文件夹下目录结构按照标准惯例为 `语言/LC_MESSAGES` 结构,其中 `LC_MESSAGES` 下存放 `mo` 文件。 - `languages=[language]` 表示需要国际化的语言,列表中可以具备多个元素,如 `"zh", "fr"` 等,会首先寻找 `zh` 中文的国际化 `mo` 文件,如果没有找到,则再找 `fr` 的国际化 `mo` 文件,直到找到为止,如果都没有找到,在 `fallback=True` 的前提下,会回退到默认语言。 ## 建立目录结构 目录结构如下: ``` 📁 Project Root ├── 📄 app.py ├── 📄 babel.cfg └── 📂 locale ``` ## 写入配置文件 在配置文件 `babel.cfg` 中写入如下内容: ```cfg [python: **.py] ``` 表示需要国际化的文件中包括所有 `py` 文件。 ## 提取模板文件 运行如下指令提取模板文件: ```cmd pybabel extract -F babel.cfg -o locale/messages.pot . ``` 生成一个 `pot` 文件 `messages.pot` 。 ## 生成中文翻译文件 运行如下指令生成中文翻译文件: ```cmd pybabel init -i locale/messages.pot -d locale -l zh ``` 会生成一个 `locale/zh/LC_MESSAGES/messages.po` 文件,文件内容如下: ```po # Chinese translations for PROJECT. # Copyright (C) 2025 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2025. # msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2025-01-22 21:07+0800\n" "PO-Revision-Date: 2025-01-22 21:33+0800\n" "Last-Translator: FULL NAME \n" "Language: zh\n" "Language-Team: zh \n" "Plural-Forms: nplurals=1; plural=0;\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" #: app.py:33 msgid "Hello, world!" msgstr "" #: app.py:35 msgid "This is a multilingual application." msgstr "" #: app.py:37 msgid "Goodbye!" msgstr "" ``` ## 手动补全翻译语言 需要翻译人员手动补全需要翻译的文件: ```po msgid "Hello, world!" msgstr "你好,世界!" msgid "This is a multilingual application." msgstr "这是一个支持多语言的程序。" msgid "Goodbye!" msgstr "再见!" ``` ## 编译中文翻译文件 需要将 `po` 文件编译为机器可读的 `mo` 文件。 运行如下指令编译中文翻译文件: ```cmd pybabel compile -d locale ``` 这会将所有的 `po` 文件全部编译为 `mo` 文件,在 `locale/zh/LC_MESSAGES` 下生成一个 `messages.mo` 文件。 ## 执行文件,观察效果 运行 `app.py` ,查看中文国际化效果: ``` PS X:\> python app.py" Please select a language: 1. English 2. 中文 (Chinese) Enter 1 or 2 to select a language: 1 Hello, world! This is a multilingual application. Goodbye! PS X:\> python app.py" Please select a language: 1. English 2. 中文 (Chinese) Enter 1 or 2 to select a language: 2 你好,世界! 这是一个支持多语言的程序。 再见! ``` 也可以继续国际化其它语言。