在没有任何参数的情况下调用脚本时,使用python argparse显示帮助消息

mus*_*XXX 203 python argparse

这可能很简单.假设我有一个使用argparse来处理命令行参数/选项的程序.以下将打印"帮助"消息:

./myprogram -h
Run Code Online (Sandbox Code Playgroud)

要么:

./myprogram --help
Run Code Online (Sandbox Code Playgroud)

但是,如果我在没有任何参数的情况下运行脚本,它就不会做任何事情.我想要它做的是在没有参数的情况下调用它时显示用法消息.怎么做的?

unu*_*tbu 252

这个答案来自Steven Bethard 在Google小组中的观点.我在此处重新发布,以便让没有Google帐户的人更容易访问.

您可以覆盖方法的默认行为error:

import argparse
import sys

class MyParser(argparse.ArgumentParser):
    def error(self, message):
        sys.stderr.write('error: %s\n' % message)
        self.print_help()
        sys.exit(2)

parser = MyParser()
parser.add_argument('foo', nargs='+')
args = parser.parse_args()
Run Code Online (Sandbox Code Playgroud)

请注意,无论何时error 触发该方法,上述解决方案都将打印帮助消息.例如,test.py --blah如果--blah不是有效选项,也将打印帮助消息.

如果只想在命令行上没有提供参数的情况下打印帮助消息,那么这可能仍然是最简单的方法:

import argparse
import sys

parser=argparse.ArgumentParser()
parser.add_argument('foo', nargs='+')
if len(sys.argv)==1:
    parser.print_help(sys.stderr)
    sys.exit(1)
args=parser.parse_args()
Run Code Online (Sandbox Code Playgroud)

请注意,parser.print_help()默认情况下打印到stdout.正如init_js建议的那样,使用parser.print_help(sys.stderr)打印到stderr.

  • 在第二个解决方案中,我使用`parser.print_usage()`来代替`parser.print_help()` - 帮助消息包含用法,但它更详细. (6认同)
  • 我本来会投票给答案的第二部分,但是重写"错误()"对我来说似乎是个糟糕的主意.它有不同的用途,它不是为打印友好用途或帮助而设计的. (5认同)
  • `sys.exit(0)` 表示程序成功结束。`sys.exit(1)` 表示程序以失败结束。 (2认同)

vac*_*cri 50

可以使用try/except来代替编写类

try:
    options = parser.parse_args()
except:
    parser.print_help()
    sys.exit(0)
Run Code Online (Sandbox Code Playgroud)

好处是工作流程更清晰,您不需要存根类.缺点是第一个"使用"行打印两次.

这至少需要一个强制性参数.如果没有强制参数,则在命令行上提供零参数是有效的.

  • 如果使用`-h`标志,此代码打印帮助2次,如果使用`--version`标志,则不必要的打印有帮助.为了缓解这些问题,您可以像这样检查错误类型:`除了SystemExit为错误:if err.code == 2:parser.print_help()` (6认同)

cgs*_*ler 21

使用argparse,您可以:

parser.argparse.ArgumentParser()
#parser.add_args here

#sys.argv includes a list of elements starting with the program
if len(sys.argv) < 2:
    parser.print_usage()
    sys.exit(1)
Run Code Online (Sandbox Code Playgroud)

  • 这必须_before_调用`parser.parse_args()` (3认同)

pd3*_*321 16

如果您必须为要运行的脚本指定参数- 请使用ArgumentParser 所需的参数,如下所示: -

parser.add_argument('--foo', required=True)
Run Code Online (Sandbox Code Playgroud)

如果脚本在没有任何参数的情况下运行,parse_args()将报告错误.

  • 我不确定这是否回答了实际问题。如果没有给出参数,OP 希望打印一条帮助消息。这个答案涉及添加必需的可选参数,这不是所要求的。最多,这只会打印一条使用消息。 (4认同)
  • 这是最简单的解决方案,也适用于指定的无效选项。 (2认同)

AMa*_*nce 16

如果您为(子)解析器关联默认函数,如下所述add_subparsers,您只需将其添加为默认操作:

parser = argparse.ArgumentParser()
parser.set_defaults(func=lambda x: parser.print_usage())
args = parser.parse_args()
args.func(args)
Run Code Online (Sandbox Code Playgroud)

如果由于缺少位置参数而引发异常,请添加try-except.

  • 这个答案被低估了。简单并且与子解析器一起工作得很好。 (2认同)
  • 很好的答案!我所做的唯一更改是使用不带参数的 lambda。 (2认同)

pau*_*ger 10

把我的版本扔进这里:

import argparse

parser = argparse.ArgumentParser()
args = parser.parse_args()
if not vars(args):
    parser.print_help()
    parser.exit(1)
Run Code Online (Sandbox Code Playgroud)

您可能会注意到parser.exit- 我主要是这样做的,因为它保存了一个导入行,如果这是sys文件中的唯一原因...

  • 不幸的是,如果缺少位置参数,parser.parse_args()将退出.所以这仅在使用可选参数时有效. (4认同)

Iev*_*ych 8

最干净的解决方案是,如果在命令行中未提供默认参数,则手动传递默认参数:

parser.parse_args(args=None if sys.argv[1:] else ['--help'])
Run Code Online (Sandbox Code Playgroud)

完整的例子:

import argparse, sys

parser = argparse.ArgumentParser()
parser.add_argument('--host', default='localhost', help='Host to connect to')
# parse arguments
args = parser.parse_args(args=None if sys.argv[1:] else ['--help'])

# use your args
print("connecting to {}".format(args.host))
Run Code Online (Sandbox Code Playgroud)

如果不带参数调用,这将打印出完整的帮助(不是简短用法)。

  • 我认为这是这里列出的最好的! (14认同)
  • 也许 `args=(sys.argv[1:] or ['--help'])` 会更短 (4认同)
  • sys.argv [1:]是一个非常常见的习惯用法。我看到`parser.parse_args(如果sys.argv [1:] else ['-h'])没有更多习惯用法和用法。 (2认同)
  • 迄今为止最干净的解决方案。有用! (2认同)
  • 确实,干净又好的解决方案 (2认同)

Nun*_*dré 6

有一对单行sys.argv[1:](一种非常常见的 Python 习语来引用命令行参数,sys.argv[0]即脚本的名称)可以完成这项工作。

第一个是不言自明的,干净的和pythonic的:

args = parser.parse_args(None if sys.argv[1:] else ['-h'])
Run Code Online (Sandbox Code Playgroud)

第二个有点hackier。将先前评估的空列表FalseTrue == 1False == 0等价的事实相结合,您将得到:

args = parser.parse_args([None, ['-h']][not sys.argv[1:]])
Run Code Online (Sandbox Code Playgroud)

也许括号太多,但如果之前选择了参数就很清楚了。

_, *av = sys.argv
args = parser.parse_args([None, ['-h']][not av])
Run Code Online (Sandbox Code Playgroud)


Tho*_*ner 5

parser.print_help()
parser.exit()
Run Code Online (Sandbox Code Playgroud)

parser.exit方法还接受一个status(返回码)和一个message值(包括您自己的尾随换行符!)。

一个固执的例子,:)

#!/usr/bin/env python3

""" Example argparser based python file
"""

import argparse

ARGP = argparse.ArgumentParser(
    description=__doc__,
    formatter_class=argparse.RawTextHelpFormatter,
)
ARGP.add_argument('--example', action='store_true', help='Example Argument')


def main(argp=None):
    if argp is None:
        argp = ARGP.parse_args()  # pragma: no cover

    if 'soemthing_went_wrong' and not argp.example:
        ARGP.print_help()
        ARGP.exit(status=64, message="\nSomething went wrong, --example condition was not set\n")


if __name__ == '__main__':
    main()  # pragma: no cover
Run Code Online (Sandbox Code Playgroud)

示例调用:

$ python3 ~/helloworld.py; 回声 $?
用法:helloworld.py [-h] [--example]

 基于 argparser 的 Python 文件示例

可选参数:
  -h, --help 显示此帮助信息并退出
  --example 示例参数

出了点问题,--示例条件未设置
64
$ python3 ~/helloworld.py --example; 回声 $?
0


小智 5

这里的大多数答案都需要sys导入另一个模块,例如 ,或者使用可选参数。我想找到一个仅使用argparse、与必需参数一起使用的答案,并且如果可能的话,可以在不捕获异常的情况下工作。我最终得到以下结果:

import argparse

if __name__ == '__main__':

    arg_parser = argparse.ArgumentParser(add_help=False)
    arg_parser.add_argument('input_file', type=str, help='The path to the input file.')
    arg_parser.add_argument('output_file', type=str, help='The path to the output file.')
    arg_parser.add_argument('-h','--help', action='store_true', help='show this help message and exit')
    arg_parser.usage = arg_parser.format_help()
    args = arg_parser.parse_args()
Run Code Online (Sandbox Code Playgroud)

主要思想是使用该format_help函数为用法语句提供帮助字符串。在调用中设置为add_help可防止帮助语句在某些情况下打印两次。但是,我必须为可选帮助参数创建一个参数,一旦设置为模仿典型的帮助消息,以便在帮助消息中显示可选帮助参数。该操作在帮助参数中设置为,以防止帮助消息在打印帮助消息时填写类似于参数的值。FalseArgumentParser()Falsestore_trueHELP