如何使Python的argparse生成非英文文本?

12
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

请展示例子和代码。 - Rico
如果你想更改“位置参数”和“可选参数”的名称,可以定义自己的argument_groups - hpaulj
@hpaulj:感谢您的建议。Jon-Eric的gettext.gettext解决方案也适用于这些名称;我只是在上面的示例中没有替换它们。 - Wolfram
5个回答

12

argparse 使用受 GNU gettext 启发的 gettext API。您可以使用此 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文件?

  1. pygettext --default-domain=argparse /usr/local/lib/python3.5/argparse.py
    • 使用实际的argparse.py位置
    • 创建文件argparse.pot
  2. cp argparse.pot argparse-ll.po
    • 使用实际的语言代码替换ll
  3. 填写argparse-ll.po中缺少的翻译字符串
  4. msgfmt argparse-ll.po -o locale/ll/LC_MESSAGES/argparse.mo

有关创建.mo文件的详细信息,请参见gettext文档

我已在我的argparse捷克翻译README.md中更详细地发布了这些说明。


4

以下是 Peter Otten 在 这篇文章 中提出的一种方法:

I don't know much about gettext, but the following suggests that most strings in argparse are properly wrapped:

$ 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

The workaround for the "-V" option would be to add the help message explicitly

parser.add_argument("-V", ..., help=_("show..."))

You still have to provide all translations yourself.


谢谢!这就是它。似乎很重要的是在重新定义gettext.gettext之后才导入argparse。 - Wolfram

3

这是一个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


一个为argparse模块提供法语翻译的项目的beta版本目前在Github上可用(https://github.com/s-ball/i18nparse)。 - LeMoussel

3
这里提供一个带有法语翻译的解决方案,其中创建一个转换字典来保存遇到的英文关键字的翻译。
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

0
我曾经遇到过类似的问题。 按照第5篇文章所述方法,几乎所有的消息都能被翻译得很好,但是使用parser.add_argument()添加的帮助消息却不能翻译。 您可以通过在argparse中使用非基于类的gettext,在应用程序中使用基于类的gettext来解决此问题。 请查看https://github.com/jmo3300/py01_i18n_01中的app3.py。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接