# 国际化(i18n) Python中的i18n可以实现程序的多语言支持。下面通过vnpy包在Windows系统上进行演示。 ## 标记字符 在源码中标记需要翻译的字符,如以下代码所示: ```python from .locale import _ output(_("参数优化空间:{}").format(len(settings))) ``` 请注意: - 不要忘记加载_函数 - 需要用format写法代替f-string ## 创建pot文件 在命令行中,调用python环境下Tools\i18n文件夹中的pygettext.py对模块所有python文件进行扫描,把所有标记过的字符都写入指定的pot模板文件,如以下代码所示: ```python python "你的python环境路径"\Tools\i18n\pygettext.py -o vnpy\trader\locale\vnpy.pot vnpy\trader\*.py vnpy\trader\ui\*.py ``` 其中-o后面是要生成的pot文件的路径,“vnpy\trader\*.py”是扫描指定文件夹下所有Python文件的示例。 ## 创建po文件 以英文版为例,在locale文件夹下创建/en/LC_MESSAGES文件夹,复制生成的pot文件到该文件夹下并修改后缀为po。 **修改po文件顶部的charset为UTF-8**,再对模板内的msgid进行翻译,如下代码所示: 修改前: ``` #: vnpy/trader/optimize.py:62 msgid "范围参数添加成功,数量{}" msgstr "" ``` 修改后: ``` #: vnpy/trader/optimize.py:62 msgid "范围参数添加成功,数量{}" msgstr "Range parameter added successfully, quantity {}" ``` 请注意标点符号的语言转换。 ## 生成mo文件 在命令行中,调用python环境下Tools\i18n文件夹中的msgfmt.py将po文件转成二进制mo文件,如以下代码所示: ```python python "你的python环境路径"\Tools\i18n\msgfmt.py -o vnpy\trader\locale\en\LC_MESSAGES\vnpy.mo vnpy\trader\locale\en\LC_MESSAGES\vnpy ``` 其中-o后面是生成mo文件的路径,最后的是po文件的路径(无需后缀名) ## 打包 打包过程中请在MANIFEST.in文件中添加```*.mo```,这样安装时才不会忽略mo文件 ## 使用 配置好系统语言,正常使用软件即可。运行时程序会读取配置的系统语言并尝试寻找对应语言翻译包。 # Internationalization (i18n) This document outlines the i18n process. Using the steps in this guide, multi-language support can be incorporated into VeighNa using standard Python conventions References: * https://docs.python.org/3.10/library/i18n.html * https://simpleit.rocks/python/how-to-translate-a-python-project-with-gettext-the-easy-way/ * https://www.mattlayman.com/blog/2015/i18n/ ## prerequisites * [gettext](https://www.gnu.org/software/gettext/) - Linux/Mac: `brew install gettext` - Windows: https://mlocati.github.io/articles/gettext-iconv-windows.html (or similar) ## mark messages The first step is to *mark* message strings for translation. We do this by wrapping the string with a special function. Example: ```python output("优化参数组合为空,请检查") ``` becomes ```python from .locale import _ output(_("优化参数组合为空,请检查")) ``` or, a parameterised message ```python output("参数优化空间:{}".format(len(settings))) ``` becomes ```python from .locale import _ output(_("参数优化空间:{}").format(len(settings))) ``` as unfortunately f-strings are not supported. One way to search for Chinese characters is to use the regex `\p{InCJK_UNIFIED_IDEOGRAPHS}` ## template files Once all the messages are marked, we run `xgettext` to extract the translatable strings into a message template file ```shell xgettext -o vnpy/trader/locale/base.pot `find ./vnpy -name "*.py"` ``` ## individual language files We then create individual language files, by copying the template. So for English and Spanish ```shell mkdir -p vnpy/trader/locale/{en, es}/LC_MESSAGES cp vnpy/trader/locale/vnpy.pot vnpy/trader/locale/en/LC_MESSAGES/vnpy.po cp vnpy/trader/locale/vnpy.pot vnpy/trader/locale/es/LC_MESSAGES/vnpy.po ``` Then edit the .po files to add the translated text, updating the `msgstr` attributes. So for English (`vnpy/trader/locale/en/LC_MESSAGES/vnpy.po`): ``` #: vnpy/trader/optimize.py:45 msgid "固定参数添加成功" msgstr "" #: vnpy/trader/optimize.py:48 msgid "参数优化起始点必须小于终止点" msgstr "" ``` becomes ``` #: vnpy/trader/optimize.py:45 msgid "固定参数添加成功" msgstr "Fixed parameters added successfully" #: vnpy/trader/optimize.py:62 msgid "范围参数添加成功,数量{}" msgstr "Range parameter added successfully, quantity {}" ``` See these projects for automation of the translation step: * https://www.deepl.com/translator * https://poeditor.com/ * https://www.transifex.com/ Quality of the automatic translation services is variable, and not always free. But they do at least provide a starting point. Sometimes a string will require a manual edit. ## binary files The plain text languages files (*.po) must be converted into the binary format (.mo) used at runtime. This would be normally done at the build stage. But to do it manually during development or testing: ```shell msgfmt -o vnpy/trader/locale/en/LC_MESSAGES/vnpy.mo vnpy/trader/locale/en/LC_MESSAGES/vnpy ``` ## install ```shell pip install . ``` ## execution Now run the application, with your chosen language specified ```shell LANG=en python vnpy/examples/veighna_trader/run.py ``` or, set the environment variable `LANG` first, then run as normal. The names 'LANGUAGE', 'LC_ALL', 'LC_MESSAGES' also work ## distribution TBD