【问题标题】:How to have the docstring respect the PEP257, while usable with docopt to comply with i18n using gettext?如何让文档字符串尊重 PEP257,同时可与 docopt 一起使用以使用 gettext 遵守 i18n?
【发布时间】:2014-05-16 14:11:53
【问题描述】:

根据PEP 257,命令行脚本的docstring应该是它的使用信息:

脚本(独立程序)的文档字符串应该可用作其“使用”消息,当使用不正确或缺少参数(或者可能使用“-h”选项调用脚本时打印)求助”)。这样的文档字符串应该记录脚本的函数和命令行语法、环境变量和文件。使用信息可以相当详细(几个屏幕已满),应该足以让新用户正确使用命令,以及为老练用户提供对所有选项和参数的完整快速参考。

文档字符串应该是模块级别的第一个字符串,在其他任何东西之前,都可以作为__doc__使用。

现在,我还使用docopt 作为使用消息解析器,所以我只需要编写文档字符串,它自己构建命令行解析器,这很棒。

_("""...""")

不太好的地方是,我找不到将文档字符串标记为 i18nable 的方法来获取文本,因此我可以将其转换为其他语言,以便将其提供给 docopt。目前我得到的唯一解决方案是在翻译所有应用程序的其他字符串时,将使用和帮助消息保持为英文!

正如PEP 20 所说:

应该有一种——最好只有一种——明显的方法。
虽然这种方式一开始可能并不明显,除非你是荷兰人。

绕过无法优雅地将文档字符串标记为可翻译的限制的最佳方法是什么?

注意:这里我们认为我正在 __init__.py 模块中执行 gettext.install(),以便在解析 __doc__ 之前,_() 就存在于内置函数中。

【问题讨论】:

  • 我怀疑使用消息的国际化必须得到docopt 的支持。你看过源代码吗?也许您可以自己进行更改并提交拉取请求以合并到上游。
  • 好吧,我还没有看,因为我从没想过我会是第一个解决这个问题的人 :-) 如果确实没有办法,我会发补丁!
  • 看了几位朋友聊天,其实是无法给python打补丁来支持标记文档字符串的。因为文档字符串是在编译时评估的,而_() 是一个函数,因此是在运行时评估的,这意味着将文档字符串移动到可能产生级联后果的运行时评估。

标签: python internationalization gettext docstring docopt


【解决方案1】:

目前,这是我正在考虑的解决方案:

"""\
This is the docstring
"""

import docopt
if __name__ == "__main__":
    try:
        args = docopt.docopt(_("{docstring}").format(docstring=__doc__))
    except KeyError:
        args = docopt.docopt(_("{docstring}")) # string which will be replaced by the i18ned one.

我不觉得那么优雅,因为即使异常在 python 中是可以的,但我认为它们应该保留在 exceptional 中,而不是在应用程序的用例中。

这也是一个非常顽皮的 hack,它将在 gettext 中获取 docstring 格式,而不是 __docopt__ 文本,这对翻译人员没有帮助,因为他们必须返回源代码......

【讨论】:

    【解决方案2】:

    我终于找到了解析文档字符串的唯一好办法:

    -D
    --docstrings
        Extract module, class, method, and function docstrings.  These do
        not need to be wrapped in _() markers, and in fact cannot be for
        Python to consider them docstrings. (See also the -X option).
    

    将提取所有文档字符串。所以唯一需要翻译的可以用:

    args = docopt.docopt(_(__doc__))
    

    【讨论】:

    • 什么命令接受这个参数,那个命令的文档在哪里?
    • 我得说那是很久以前的事了,所以我不得不再次查找以找出我在说什么^^所以这是pygettext工具!
    【解决方案3】:

    另一种方式:

    if __name__ == "__main__":
        if hasattr(vars()['__builtins__'], '_') and not 'NullTranslations' in str(_):
            args = docopt.docopt(_("USAGE MESSAGE"))
        else:
            args = docopt.docopt(__doc__)
    

    它没有使用异常,而是使用方法的字符串表示测试键入,并在内置模块中查找该方法......这并不比其他选项更好。

    这也是一个非常糟糕和不雅的hack,因为翻译人员必须参考源代码来查找文档字符串。或者我必须在代码中包含两倍于文档字符串的内容。

    【讨论】:

      猜你喜欢
      • 2010-11-18
      • 2012-09-17
      • 2013-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-10
      • 1970-01-01
      相关资源
      最近更新 更多