如何让Python的argparse生成非英语文本?
argparse模块可以“自动生成帮助和使用信息”。我可以给参数起非英语的名字,并提供非英语的帮助文本;但这样一来,帮助输出就会变成至少两种语言的混合,因为像usage
、positional arguments
、optional arguments
和show this help message and exit
这些术语都是自动用英语生成的。
我该如何把这些英语输出替换成翻译后的内容呢?
最好是我能在脚本里提供这些翻译,这样无论在哪儿启动这个脚本,输出都是一样的。
编辑:根据Jon-Eric的回答,这里有一个他的解决方案的例子:
import gettext
def Übersetzung(Text):
Text = Text.replace("usage", "Verwendung")
Text = Text.replace("show this help message and exit",
"zeige diese Hilfe an und tue nichts weiteres")
Text = Text.replace("error:", "Fehler:")
Text = Text.replace("the following arguments are required:",
"Die folgenden Argumente müssen angegeben werden:")
return Text
gettext.gettext = Übersetzung
import argparse
Parser = argparse.ArgumentParser()
Parser.add_argument("Eingabe")
Argumente = Parser.parse_args()
print(Argumente.Eingabe)
保存为Beispiel.py
,用python3 Beispiel.py -h
运行时,会得到以下帮助输出:
Verwendung: Beispiel.py [-h] Eingabe
positional arguments:
Eingabe
optional arguments:
-h, --help zeige diese Hilfe an und tue nichts weiteres
5 个回答
我遇到过类似的问题。几乎所有的消息都能按照第5个帖子里说的方法正确翻译,但用parser.add_argument()
添加的帮助信息却不行。你可以通过对argparse使用非类的gettext
,而对应用程序使用类的gettext
来解决这个问题。可以看看app3.py,地址在https://github.com/jmo3300/py01_i18n_01。
这里有一个Python模块,可以翻译argparse发出的所有消息。这个模块的目的是为了快速简单地把消息翻译成另一种语言(我这里是法语,但你可以根据自己的需要调整成其他语言)。如果你想要更专业的多语言解决方案,可以看看Filip Bartek的优秀方案。
"""
This module is like argparse but in french.
Import it and use it like you would use argparse.
DIRECTIVES:
First copy-paste this code in a separate new file named french_argparse.py
Put this new file beside your main.py file in the same top project folder.
Then in the main.py file, import it like this:
>>> import french_argparse as argparse
"""
import gettext
#################################################################################################################
# The following translations are in French, but feel free to replace them with your own
# Many messages are even not translated, because they seems to be more intended for the programmer than the user.
# Phrases were extracted from the code at (https://github.com/python/cpython/blob/master/Lib/argparse.py)
# On October 2019
#################################################################################################################
__TRANSLATIONS = {
'ambiguous option: %(option)s could match %(matches)s': 'option ambiguë: %(option)s parmi %(matches)s',
'argument "-" with mode %r': 'argument "-" en mode %r',
'cannot merge actions - two groups are named %r': 'cannot merge actions - two groups are named %r',
"can't open '%(filename)s': %(error)s": "can't open '%(filename)s': %(error)s",
'dest= is required for options like %r': 'dest= is required for options like %r',
'expected at least one argument': 'au moins un argument est attendu',
'expected at most one argument': 'au plus un argument est attendu',
'expected one argument': 'un argument est nécessaire',
'ignored explicit argument %r': 'ignored explicit argument %r',
'invalid choice: %(value)r (choose from %(choices)s)': 'choix invalide: %(value)r (parmi %(choices)s)',
'invalid conflict_resolution value: %r': 'invalid conflict_resolution value: %r',
'invalid option string %(option)r: must start with a character %(prefix_chars)r':
'invalid option string %(option)r: must start with a character %(prefix_chars)r',
'invalid %(type)s value: %(value)r': 'valeur invalide de type %(type)s: %(value)r',
'mutually exclusive arguments must be optional': 'mutually exclusive arguments must be optional',
'not allowed with argument %s': "pas permis avec l'argument %s",
'one of the arguments %s is required': 'au moins un argument requis parmi %s',
'optional arguments': 'arguments optionnels',
'positional arguments': 'arguments positionnels',
"'required' is an invalid argument for positionals": "'required' is an invalid argument for positionals",
'show this help message and exit': 'afficher ce message et quitter',
'unrecognized arguments: %s': 'argument non reconnu: %s',
'unknown parser %(parser_name)r (choices: %(choices)s)': 'unknown parser %(parser_name)r (choices: %(choices)s)',
'usage: ': 'usage: ',
'%(prog)s: error: %(message)s\n': '%(prog)s: erreur: %(message)s\n',
'%r is not callable': '%r is not callable',
}
gettext.gettext = lambda text: __TRANSLATIONS[text] or text
##############################################################################
# Now import all argparse functionalities inside this module.
#
# NB Many linters don't like the following line of code so we have disabled
# warnings for pylint, flake8 and PyCharm
##############################################################################
# pylint: disable=all
# noinspection PyUnresolvedReferences
from argparse import * # noqa
这里有一个解决方案,里面包含了法语翻译。这个方法是创建一个转换字典,用来存放遇到的英文关键词的翻译。
def convertArgparseMessages(s):
subDict = \
{'positional arguments':'Arguments positionnels',
'optional arguments':'Arguments optionnels',
'show this help message and exit':'Affiche ce message et quitte'}
if s in subDict:
s = subDict[s]
return s
gettext.gettext = convertArgparseMessages
import argparse
argparse
使用了一种叫做 gettext
API 的工具,这个工具是受到 GNU gettext 的启发。你可以用这个 API 来比较干净地整合你对 argparse
的翻译。
要做到这一点,在 argparse
输出任何文本之前(但可以在 import argparse
之后)调用以下代码:
import gettext
# Use values that suit your project instead of 'argparse' and 'path/to/locale'
gettext.bindtextdomain('argparse', 'path/to/locale')
gettext.textdomain('argparse')
为了让这个方法有效,你的 argparse
翻译文件必须放在 path/to/locale/ll/LC_MESSAGES/argparse.mo
这个路径下,其中 ll
是当前语言的代码(比如 de
;你可以通过设置环境变量 LANGUAGE
来配置)。
如何生成 .mo
文件?
pygettext --default-domain=argparse /usr/local/lib/python3.5/argparse.py
- 使用
argparse.py
的实际路径 - 会生成一个叫
argparse.pot
的文件
- 使用
cp argparse.pot argparse-ll.po
- 用实际的语言代码替换
ll
- 用实际的语言代码替换
- 在
argparse-ll.po
文件中填写缺失的翻译内容 msgfmt argparse-ll.po -o locale/ll/LC_MESSAGES/argparse.mo
有关如何创建 .mo
文件的详细信息,请查看 gettext
文档。
我在我的 Czech translation of argparse
的 README.md 中详细发布了这些说明。
这里有一种方法,来自Peter Otten的这篇帖子:
我对gettext了解不多,但以下内容表明,argparse中的大多数字符串都已经正确处理了:
$ cat localize_argparse.py import gettext def my_gettext(s): return s.upper() gettext.gettext = my_gettext import argparse if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("-V", action="version") args = parser.parse_args() $ python localize_argparse.py -h USAGE: localize_argparse.py [-h] [-V] OPTIONAL ARGUMENTS: -h, --help SHOW THIS HELP MESSAGE AND EXIT -V show program's version number and exit
对于“-V”这个选项的解决办法是明确添加帮助信息
parser.add_argument("-V", ..., help=_("show..."))
不过,你仍然需要自己提供所有的翻译。