使用Python的optparse模块时如何遵守PEP 257文档字符串?

wie*_*rob 5 python optparse

根据PEP 257,命令行脚本的docstring应该是它的用法消息.

脚本(独立程序)的docstring应该可用作其"用法"消息,当使用不正确或缺少的参数(或者可能使用"-h"选项,"help")调用脚本时打印.这样的docstring应记录脚本的功能和命令行语法,环境变量和文件.用法消息可以相当复杂(几个屏幕已满),并且应该足以让新用户正确使用该命令,以及对复杂用户的所有选项和参数的完整快速参考.

所以我的docstring看起来像这样:

<tool name> <copyright info>

Usage: <prog name> [options] [args]

some text explaining the usage...

Options:
  -h, --help  show this help message and exit
   ...

现在我想使用optparse模块.optparse生成"选项"部分和解释命令行语法的"用法":

from optparse import OptionParser

if __name__ == "__main__":
    parser = OptionParser()
    (options, args) = parser.parse_args() 
Run Code Online (Sandbox Code Playgroud)

因此,使用"-h"标志调用脚本将打印:

Usage: script.py [options]

Options:
    -h, --help  show this help message and exit

这可以修改如下:

parser = OptionParser(usage="Usage: %prog [options] [args]",
                      description="some text explaining the usage...")
Run Code Online (Sandbox Code Playgroud)

结果

Usage: script.py [options] [args]

some text explaining the usage...

Options:
  -h, --help  show this help message and exit

但是我怎么能在这里使用docstring呢?将docstring作为用法消息传递有两个问题.

  1. 如果不以"用法:"开头,optparse会将"Usage:"附加到docstring
  2. 必须在docstring中使用占位符'%prog'

结果

根据答案,似乎无法重用optparse模块所预期的文档字符串.所以剩下的选择是手动解析文档字符串并构造OptionParser.(所以我会接受S.Loot的回答)

"Usage:"部分由IndentedHelpFormatter引入,可以用OptionParser .__ init __()中的formatter参数替换.

Vla*_*hev 6

我写了一个模块docopt来完成你想要的 - 在docstring中编写用法消息并保持DRY.它还允许避免编写繁琐的OptionParser代码,因为它docopt是基于用法消息生成解析器.

看看:http://github.com/docopt/docopt

"""Naval Fate.

Usage:
  naval_fate.py ship new <name>...
  naval_fate.py ship [<name>] move <x> <y> [--speed=<kn>]
  naval_fate.py ship shoot <x> <y>
  naval_fate.py mine (set|remove) <x> <y> [--moored|--drifting]
  naval_fate.py -h | --help
  naval_fate.py --version

Options:
  -h --help     Show this screen.
  --version     Show version.
  --speed=<kn>  Speed in knots [default: 10].
  --moored      Moored (anchored) mine.
  --drifting    Drifting mine.

"""
from docopt import docopt


if __name__ == '__main__':
    arguments = docopt(__doc__, version='Naval Fate 2.0')
    print(arguments)
Run Code Online (Sandbox Code Playgroud)


S.L*_*ott 4

选择1:复制并粘贴。不干燥,但可行。

选择 2:解析您自己的文档字符串以删除描述段落。它始终是第二段,因此您可以按“\n\n”进行拆分。

usage, description= __doc__.split('\n\n')[:2]
Run Code Online (Sandbox Code Playgroud)

由于optparse生成用法,您可能不想为其提供用法语句。您的用法版本可能是错误的。如果您坚持向 提供用法字符串optparse,我会将其作为练习,让读者了解如何"Usage: "从上面生成的字符串的前面删除usage