假设我有一个使用argparse处理命令行参数/选项的程序。下面将打印“帮助”信息:

./myprogram -h

or:

./myprogram --help

但是,如果我不带任何参数运行脚本,它什么都不会做。我想要它做的是在不带参数地调用它时显示用法消息。怎么做呢?


当前回答

这个答案来自谷歌groups的Steven Bethard。我在这里重新发布它,让没有谷歌账户的人更容易访问。

你可以重写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()

请注意,上面的解决方案将打印帮助消息每当出现错误 方法触发。例如,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()

注意parser.print_help()默认情况下打印到标准输出。正如init_js所建议的,使用parser.print_help(sys.stderr)来打印到stderr。

其他回答

parser.print_help()
parser.exit()

解析器。Exit方法还接受一个状态(returncode)和一个消息值(包括一个尾随换行符自己!)。

举个固执己见的例子, :)

#!/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

示例调用:

$ python3 ~/helloworld.py; echo $?
usage: helloworld.py [-h] [--example]

 Example argparser based python file

optional arguments:
  -h, --help  show this help message and exit
  --example   Example Argument

Something went wrong, --example condition was not set
64
$ python3 ~/helloworld.py --example; echo $?
0

这并不好(因为会拦截所有错误),但是:

def _error(parser):
    def wrapper(interceptor):
        parser.print_help()

        sys.exit(-1)

    return wrapper

def _args_get(args=sys.argv[1:]):
    parser = argparser.ArgumentParser()

    parser.error = _error(parser)

    parser.add_argument(...)
    ...

下面是ArgumentParser类的错误函数的定义。

如您所见,下面的签名有两个参数。然而,类之外的函数对第一个参数self一无所知,因为粗略地说,这个参数是类的。

def _error(self, message):
    self.print_help()

    sys.exit(-1)

def _args_get(args=sys.argv[1:]):
    parser = argparser.ArgumentParser()

    parser.error = _error
    ...

将输出:

"AttributeError: 'str' object has no attribute 'print_help'"

你可以在_error函数中传递parser (self),通过调用它:

def _error(self, message):
    self.print_help()

    sys.exit(-1)

def _args_get(args=sys.argv[1:]):
    parser = argparser.ArgumentParser()

    parser.error = _error(parser)
    ...

但是如果你现在不想退出程序,返回它:

def _error(parser):
    def wrapper():
        parser.print_help()

        sys.exit(-1)

    return wrapper

尽管如此,解析器并不知道它已被修改。因此,当发生错误时,它将打印错误的原因(顺便说一下,这是一个本地化的翻译)。所以截取它:

def _error(parser):
    def wrapper(interceptor):
        parser.print_help()

        sys.exit(-1)

    return wrapper

现在,当发生错误时,解析器将打印错误的原因,您将拦截它,查看它,然后……扔掉。

如果你为(sub)解析器关联默认函数,就像在add_subparsers中提到的那样,你可以简单地将它作为默认动作添加:

parser = argparse.ArgumentParser()
parser.set_defaults(func=lambda x: parser.print_usage())
args = parser.parse_args()
args.func(args)

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

我喜欢让事情尽可能简单,这很有效:

#!/usr/bin/env python3
Description = """Tool description"""
Epilog  = """toolname.py -a aflag -b bflag  with these combined it does blah"""
arg_parser = argparse.ArgumentParser(
    formatter_class=argparse.RawDescriptionHelpFormatter,
    description=Description, 
    epilog=Epilog,
)
    try:
        if len(sys.argv) == 1:
            arg_parser.print_help()
    except Exception as e:
        print(e)

这就是我如何开始我的所有工具,因为它总是好的包括一些例子

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

第一个是不言自明的、干净的、python式的:

args = parser.parse_args(None if sys.argv[1:] else ['-h'])

第二个问题有点棘手。结合前面评估的事实,一个空列表是False与True == 1和False == 0等价,你得到:

args = parser.parse_args([None, ['-h']][not sys.argv[1:]])

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

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