当不带任何参数调用脚本时,使用 python argparse 显示帮助消息

StackOverflow https://stackoverflow.com/questions/4042452

  •  27-09-2019
  •  | 
  •  

这可能是一个简单的问题。假设我有一个使用 argparse 处理命令行参数/选项的程序。以下将打印“帮助”消息:

./myprogram -h

或者:

./myprogram --help

但是,如果我在没有任何参数的情况下运行脚本,它不会执行任何操作。我想要它做的是在不带参数调用它时显示使用消息。这是怎么做到的?

有帮助吗?

解决方案

这个答案来自史蒂文·贝萨德 在 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()

请注意,上述解决方案将在以下情况下打印帮助消息: 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()

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

其他提示

而不是写一类的,在try /除了可以用来代替

try:
    options = parser.parse_args()
except:
    parser.print_help()
    sys.exit(0)

好处是,工作流程更清晰,你并不需要一个存根类。缺点是,第一个“使用”线被印刷两次。

这将需要至少一个强制性的参数。与没有强制性的参数,在命令行上提供零个ARGS是有效的。

使用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)

如果你有必须为脚本中指定的参数来运行 - 使用需要如下所示参数ArgumentParser: -

parser.add_argument('--foo', required=True)

parse_args()将如果脚本没有任何参数运行报告一个错误。

如果您关联(子)解析器的默认函数,如下所述 add_subparsers, ,您可以简单地将其添加为默认操作:

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

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

投掷我的版本成桩的位置:

import argparse

parser = argparse.ArgumentParser()
args = parser.parse_args()
if not vars(args):
    parser.print_help()
    parser.exit(1)

您可能会注意到parser.exit - 我主要做的一样,因为它节省了进口线,如果这是对sys文件中的唯一原因......

在干净的解决方案将是手动传递默认参数,如果没有在命令行上给出:

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

完整示例:

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))

如果所谓的W / O参数这将打印完整的帮助(不是短期使用)。

有一对单行与sys.argv[1:](一种非常常见的Python的成语指命令行参数,作为sys.argv[0]脚本的名称)可以做的工作。

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

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

第二个是一点点hackier。结合先前评估的事实,即空列表是FalseTrue == 1False == 0等同你得到这样的:

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

也许太多的括号,但相当清楚,如果前一个参数的选择作出。

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

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=128, message="\nI just don't know what went wrong, maybe missing --example condition?\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

I just don't know what went wrong, maybe missing --example condition?
128
$ python3 ~/helloworld.py --example; echo $?
0

设置位置参数与NARGS,并检查是否位置ARGS是空的。

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('file', nargs='?')
args = parser.parse_args()
if not args.file:
    parser.print_help()

参考的Python NARGS

下面是另一种方式来做到这一点,如果你需要,你想显示帮助,如果特定PARAMS传递灵活的东西,根本就没有或超过1冲突的ARG:

import argparse
import sys

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-d', '--days', required=False,  help="Check mapped inventory that is x days old", default=None)
    parser.add_argument('-e', '--event', required=False, action="store", dest="event_id",
                        help="Check mapped inventory for a specific event", default=None)
    parser.add_argument('-b', '--broker', required=False, action="store", dest="broker_id",
                        help="Check mapped inventory for a broker", default=None)
    parser.add_argument('-k', '--keyword', required=False, action="store", dest="event_keyword",
                        help="Check mapped inventory for a specific event keyword", default=None)
    parser.add_argument('-p', '--product', required=False, action="store", dest="product_id",
                        help="Check mapped inventory for a specific product", default=None)
    parser.add_argument('-m', '--metadata', required=False, action="store", dest="metadata",
                        help="Check mapped inventory for specific metadata, good for debugging past tix", default=None)
    parser.add_argument('-u', '--update', required=False, action="store_true", dest="make_updates",
                        help="Update the event for a product if there is a difference, default No", default=False)
    args = parser.parse_args()

    days = args.days
    event_id = args.event_id
    broker_id = args.broker_id
    event_keyword = args.event_keyword
    product_id = args.product_id
    metadata = args.metadata
    make_updates = args.make_updates

    no_change_counter = 0
    change_counter = 0

    req_arg = bool(days) + bool(event_id) + bool(broker_id) + bool(product_id) + bool(event_keyword) + bool(metadata)
    if not req_arg:
        print("Need to specify days, broker id, event id, event keyword or past tickets full metadata")
        parser.print_help()
        sys.exit()
    elif req_arg != 1:
        print("More than one option specified. Need to specify only one required option")
        parser.print_help()
        sys.exit()

    # Processing logic here ...

干杯!

如果您的命令是什么,其中用户的需要来选择一些操作,然后使用一个互斥组的与需要=真

这是一种延伸到由pd321给出的答案的。

import argparse

parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("--batch", action='store', type=int,  metavar='pay_id')
group.add_argument("--list", action='store_true')
group.add_argument("--all", action='store_true', help='check all payments')

args=parser.parse_args()

if args.batch:
    print('batch {}'.format(args.batch))

if args.list:
    print('list')

if args.all:
    print('all')

输出:

  

$ python3 a_test.py结果   用法:a_test.py [-h](--batch pay_id | --list | --all)点击   a_test.py:错误:其中一个参数--batch --list --all需要

此只给出基本的帮助。还有一些其他的答案会给你充分的帮助。但至少你的用户知道他们可以做的 -h

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top