【问题标题】:How to comply to PEP 257 docstrings when using Python's optparse module?使用 Python 的 optparse 模块时如何遵守 PEP 257 文档字符串?
【发布时间】:2010-11-18 14:25:16
【问题描述】:

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

脚本的文档字符串(a 独立程序)应该可用 作为它的“使用”消息,打印时 脚本调用不正确 或缺少论据(或可能与 “-h”选项,用于“帮助”)。这样一个 docstring 应该记录脚本的 函数和命令行语法, 环境变量和文件。 使用信息可以相当详细 (几个屏幕已满),应该是 足以让新用户使用 命令正确,以及 完整的快速参考 选项和参数 成熟的用户。

所以我的文档字符串看起来像这样:

用法: [options] [args] 一些解释用法的文字... 选项: -h, --help 显示此帮助信息并退出 ...

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

from optparse import OptionParser

if __name__ == "__main__":
    parser = OptionParser()
    (options, args) = parser.parse_args() 

所以调用带有“-h”标志的脚本会打印:

用法:script.py [选项] 选项: -h, --help 显示此帮助信息并退出

这可以修改如下:

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

导致

用法:script.py [选项] [参数] 一些解释用法的文字... 选项: -h, --help 显示此帮助信息并退出

但是我怎样才能在这里使用文档字符串呢?将文档字符串作为使用消息传递有两个问题。

  1. optparse 如果文档字符串不以“Usage:”开头,则将“Usage:”附加到文档字符串中
  2. 必须在文档字符串中使用占位符“%prog”

结果

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

“Usage:”部分由 IndentedHelpFormatter 引入,可替换为 OptionParser.__init__() 中的 formatter 参数。

【问题讨论】:

    标签: python optparse


    【解决方案1】:

    我写了一个模块 docopt 来做你想做的事——在文档字符串中写使用消息并保持 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)
    

    【讨论】:

      【解决方案2】:

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

      选择 2:解析您自己的文档字符串以删除描述段落。它总是第二段,所以你可以在 '\n\n' 上拆分。

      usage, description= __doc__.split('\n\n')[:2]
      

      由于optparse 生成用法,您可能不想向它提供用法语句。你的用法我错了。如果您坚持要为optparse 提供一个用法字符串,我将把它留作练习,让读者了解如何从上面生成的usage 字符串的前面删除"Usage: "

      【讨论】:

      • 我喜欢第二种解决方案。不是很干净,但聪明务实。
      • 由于段落之间的空行是 RST 标准,这可以节省在 doc 上运行完整的 Docutils 解析并获得 - 根据定义 - 预期的结果。跨度>
      • 这可能是描述的一个选项。但我仍然无法重用“使用”部分,并且 optparse 强制消息以“使用:”开头。
      【解决方案3】:

      我认为我们必须对这个 PEP 的建议保持理性——我认为可以将模块留下 __doc__ 作为总结长期使用的简短描述。但如果你是完美主义者:

      '''<tool name>
      
      The full description and usage can be generated by optparse module.
      
      Description: ...
      
      '''
      
      ...
      
      # Generate usage and options using optparse.
      usage, options = ... 
      
      # Modify the docstring on the fly.
      docstring = __doc__.split('\n\n')
      docstring[1:2] = [__license__, usage, options]
      __doc__ = '\n\n'.join(docstring)
      

      【讨论】:

        猜你喜欢
        • 2013-05-08
        • 1970-01-01
        • 1970-01-01
        • 2021-11-06
        • 1970-01-01
        • 2023-01-04
        • 2021-05-03
        • 1970-01-01
        • 2023-02-24
        相关资源
        最近更新 更多