首页 文章

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

提问于
浏览
175

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

./myprogram -h

要么:

./myprogram --help

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

11 回答

  • 0

    这个答案来自Steven Bethard on Google groups . 我在此处重新发布,以便让没有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 方法,上述解决方案就会打印帮助消息 . 例如,如果 --blah 不是有效选项, test.py --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() 默认打印到stdout . 如init_js suggests,使用 parser.print_help(sys.stderr) 打印到stderr .

  • 1

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

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

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

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

  • 224

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

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

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

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

  • 9

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

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

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

  • 18

    把我的版本扔进这里:

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

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

  • 13

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

    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参数,这将打印完整的帮助(而不是简短的用法) .

  • 2

    有一对单行与 sys.argv[1:] (一个非常常见的Python的习惯用法来引用命令行参数,是脚本的名字),可以完成这项工作 .

    第一个是不言自明的,清洁和pythonic:

    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])
    
  • 40
    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
    
  • 4

    使用nargs设置位置参数,并检查位置参数是否为空 .

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

    参考Python nargs

  • 8

    这是另一种方法,如果你需要一些灵活的东西,你想要显示帮助,如果特定的参数传递,没有一个或多于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 ...
    

    干杯!

相关问题