根据PEP 257,命令行脚本的文档字符串应该是它的用法消息:
一个脚本(一个独立的程序)的文档字符串应该可以作为它的"用法"消息使用,当脚本被不正确的或缺少参数调用时(或者可能使用"-h"选项,表示"帮助")打印出来。这样的文档字符串应该记录脚本的函数和命令行语法、环境变量和文件。使用消息可以相当详细(满几个屏幕),应该足以让新用户正确使用命令,并为资深用户提供所有选项和参数的完整快速参考。
并且docstring应该是模块级别的第一个字符串,在其他任何字符串之前,作为__doc__
可用。
现在,我也使用docopt
作为用法消息解析器,所以我只需要编写doc字符串,它自己构建命令行解析器,这很好。
_("""...""")
什么不是那么伟大,是我找不到一种方法来标记文档字符串为i18nable为gettext,所以我可以将其转换为其他语言时给予docopt
。当时我得到的唯一解决方案是使用法和帮助消息保持在英语中,当所有应用程序的其他字符串被翻译!
如PEP 20所述:
应该有一种——最好只有一种——明显的方法来做到这一点。
尽管这种方法一开始可能并不明显,除非你是荷兰人。
绕过不能优雅地将文档字符串标记为可翻译的限制的最佳方法是什么?
注意::在这里,我们认为我在__init__.py
模块中做gettext.install()
,以便_()
在__doc__
被解析之前存在于内置中。
目前,我正在考虑这样一个解决方案:
"""
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中是可以的,但我认为它们应该被保留在异常的地方,而不是应用程序用例中的东西。
这也是一个相当顽皮的hack,将得到docstring格式的gettext而不是__docopt__
文本,这将不会帮助翻译人员,因为他们将不得不回到源代码…
我终于找到了解析文档字符串的唯一好的解决方案:
-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__))
另一种说法:
if __name__ == "__main__":
if hasattr(vars()['__builtins__'], '_') and not 'NullTranslations' in str(_):
args = docopt.docopt(_("USAGE MESSAGE"))
else:
args = docopt.docopt(__doc__)
没有使用异常,而是使用方法的字符串表示来测试键入,并在内置模块中查找该方法…这并不比其他选择好。
这也是一个非常糟糕和不优雅的hack,因为翻译人员将不得不参考源代码来查找doc字符串。或者我必须在代码中使用两倍于docstring的内容