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

发布于 2024-08-01 17:09:54 字数 1718 浏览 5 评论 0原文

根据 PEP 257 命令行的文档字符串script 应该是它的使用消息。

脚本的文档字符串(a 独立程序)应该可用 作为其“使用”消息,在以下时间打印 脚本调用不正确 或缺少参数(或者可能与 “-h”选项,用于“帮助”)。 这样一个 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() 

因此,使用“-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...")

结果是

Usage: script.py [options] [args]

some text explaining the usage...

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

But how can I use the docstring here? 将文档字符串作为使用消息传递有两个问题。

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

结果

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

“用法:”部分是由IndentedHelpFormatter引入的,可以用OptionParser.__init__()中的格式化程序参数替换。

According to PEP 257 the docstring of command line script should be its usage message.

The docstring of a script (a
stand-alone program) should be usable
as its "usage" message, printed when
the script is invoked with incorrect
or missing arguments (or perhaps with
a "-h" option, for "help"). Such a
docstring should document the script's
function and command line syntax,
environment variables, and files.
Usage messages can be fairly elaborate
(several screens full) and should be
sufficient for a new user to use the
command properly, as well as a
complete quick reference to all
options and arguments for the
sophisticated user.

So my docstring would look something like this:

<tool name> <copyright info>

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

some text explaining the usage...

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

Now I want to use the optparse module. optparse generates the "Options" sections and a "usage" explaining the command line syntax:

from optparse import OptionParser

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

So calling the script with the "-h" flag prints:

Usage: script.py [options]

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

This can be modified as follows:

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

which results in

Usage: script.py [options] [args]

some text explaining the usage...

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

But how can I use the docstring here? Passing the docstring as the usage message has two problems.

  1. optparse appends "Usage: " to the docstring if it does not start with "Usage: "
  2. The placeholder '%prog' must be used in the docstring

Result

According to the answers it seems that there is no way to reuse the docstring intended by the optparse module. So the remaining option is to parse the docstring manually and construct the OptionParser. (So I'll accept S.Loot's answer)

The "Usage: " part is introduced by the IndentedHelpFormatter which can be replaced with the formatter parameter in OptionParser.__init__().

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

宫墨修音 2024-08-08 17:09:54

我编写了一个模块 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)

I wrote a module docopt to do exactly what you want – write usage-message in docstring and stay DRY.
It also allows to avoid writing tedious OptionParser code at all, since docopt is generating parser
based on the usage-message.

Check it out: 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)
逆流 2024-08-08 17:09:54

我认为我们必须合理地对待这个 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)

I think we have to be reasonable about this PEP's advice -- I would think it's fine to leave the module with __doc__ being the short description that summarizes long usage. But if you're perfectionist:

'''<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)
此岸叶落 2024-08-08 17:09:54

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

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

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

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

Choice 1: Copy and paste. Not DRY, but workable.

Choice 2: Parse your own docstring to strip out the description paragraph. It's always paragraph two, so you can split on '\n\n'.

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

Since optparse generates usage, you may not want to supply the usage sentence to it. Your version of the usage my be wrong. If you insist on providing a usage string to optparse, I'll leave it as an exercise for the reader to work out how to remove "Usage: " from the front of the usage string produced above.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文