如何以可移植的方式本地化argparse生成的消息?

时间:2018-11-05 16:25:39

标签: python internationalization argparse

上下文:

我正在开发一个小模块,根据其exif时间戳自动在目录中重命名照片(目标:轻松混合来自不同相机或智能手机的照片)。它既可以作为Python包运行,也可以通过argparse通过一个小型包装直接从命令行直接运行。

我刚刚有了一个(相当愚蠢的)想法将它本地化为非英语语言。好的,gettext是我自己编写代码的朋友,但是当我遇到agparse生成的消息时,发现自己处于草率的状态...

当前研究:

我已经在SO上找到了一些资源:

最后都是将argparse中的相​​关字符串添加到po / mo文件中,并让argparse模块自动使用转换后的字符串,因为它们内部使用了_(...)包装器。到目前为止,一切都很好。

我的问题:

我觉得这是一种解决方法,而不是干净整洁的解决方案,因为:

  • 我在Python官方文档中找不到一个建议的词
  • 它似乎是一个正在进行的 :未记录下来,因此在将来的Python版本中某些字符串可能会更改(或者我错过了什么?)

当前代码:

parser = argparse.ArgumentParser(
    prog = prog,
    description="Rename pictures according to their exif timestamp")
parser.add_argument("-v", "--version", action="version",
                    version="%(prog)s " + __version__)
parser.add_argument("--folder", "-f", default = ".",
                    help = "folder containing files to rename")
parser.add_argument("-s", "--src_mask", default="DSCF*.jpg",
                    help = "pattern to select the files to rename")
parser.add_argument("-d", "--dst_mask", default="%Y%m%d_%H%M%S",
                    help = "format for the new file name")
parser.add_argument("-e", "--ext", default=".jpg", dest="ext_mask",
                    help = "extension for the new file name")
parser.add_argument("-r", "--ref_file", default="names.log",
                    help = "a file to remember the old names")
parser.add_argument("-D", "--debug", action="store_true",
                    help = "print a line per rename")
parser.add_argument("-X", "--dry_run", action="store_true", dest="dummy",
                    help = "process normally except no rename occurs")

# subcommands configuration (rename, back, merge)
subparser = parser.add_subparsers(dest='subcommand', help="sub-commands")
ren = subparser.add_parser("rename", help=
                           "rename files by using their exif timestamp")
ren.add_argument("files", nargs="*",
                  help = "files to process (default: src_mask)")
back = subparser.add_parser("back",
                            help="rename files back to their original name")
back.add_argument("files", nargs="*",
                   help = "files to process (default: content of ref_file)")
merge = subparser.add_parser("merge",
                             help="merge files from a different folder")
merge.add_argument("src_folder", metavar="folder",
                    help = "folder from where merge picture files")
merge.add_argument("files", nargs="*",
                  help = "files to process (default: src_mask)")

我知道如何用_()来包装我自己的字符串,并且 usage help 消息可能可以获得可接受的翻译,但是还有很多用户提供了错误的语法时出现的错误消息,我想防止法语程序中间出现英语错误消息...

问题:

是否可以保证argparse模块中的字符串实现不会改变,或者是否有更健壮/便携式的方式来为其消息提供翻译?

1 个答案:

答案 0 :(得分:0)

经过更多研究和@hpaulj的精彩评论,我可以确认:

  • 来自argparse的可本地化消息从3.3向上兼容到当前版本(旧消息从未更改,但为新功能添加了新消息)
  • 以上在3.3之前是不正确的
  • 2.7略有不同

这意味着这里只有2条路径:

  • 接受风险并提供当前版本的翻译,该版本将接受任何大于等于3.3的Python版本-风险是将来的版本会破坏翻译或添加新的(未翻译的)消息。无需多说,因为这将明确使用模块的实现细节
  • 完全不使用argparse模块,并基于getopt构建自定义解析器。对于不需要argparse
  • 的全部功能的简单用例,这可能是一个可接受的选项。

没有一个真的很好,但是我无法想象会有更好的...

我将尝试在github或gitlab上设置一个项目,以提供当前argparse的pot文件和法语翻译,并使其在PyPI上可用。如果有的话,我将在此处添加引用,并很高兴在此包含其他语言。


GitHUB上目前提供了一个为argparse模块提供法语翻译的项目的Beta版本。

之所以将其称为Beta是因为目前尚未对其进行广泛的测试,但是可以直接使用它,也可以作为可以做什么的示例。二进制轮包含一个小的endian mo文件,但是源代码分发允许通过包含来自CPython的Tools i18n的msgfmt.py文件的副本,而在目标系统上自动生成mo文件,而没有其他依赖性。 / p>