【问题标题】:How to include one positional argument into argparse mutually exclusive group?如何将一个位置参数包含到 argparse 互斥组中?
【发布时间】:2013-03-29 06:52:48
【问题描述】:

我知道将多个位置参数放入一个互斥的组是没有意义的,因为你不能说谁是谁。但我需要在其中包含一个位置参数。

我需要什么:

$ myprogram -h
usage: myprogram [-h] [--delete value | --update value | value]

其中位置value 是默认操作(类似于“--include”)。 (myprogram 不带参数也必须有效)。

我的第一次尝试(这不起作用):

parser = ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument('--delete', metavar='value')
group.add_argument('--update', metavar='value')
group.add_argument('value')

这可能吗?


第二次尝试:

parser = ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument('--delete', action='store_true')
group.add_argument('--update', action='store_true')
group.add_argument('--insert', action='store_true', default=True)
group.add_argument('value')

【问题讨论】:

    标签: python argparse


    【解决方案1】:

    我会做一些不同的事情:

    parser = ArgumentParser()
    group = parser.add_mutually_exclusive_group()
    group.set_defaults(mode='insert')
    group.add_argument('--delete', action='store_const', dest='mode', const='delete')
    group.add_argument('--update', action='store_const', dest='mode', const='update')
    group.add_argument('--insert', action='store_const', dest='mode', const='insert')
    parser.add_argument('value', nargs='?')
    args = parser.parse_args()
    

    如果你还想让program --delete(没有value选项)失败,添加

    if args.mode != 'insert' and args.value:
        parser.error("can't {} without a value argument".format(args.mode))
    

    请注意,这意味着program --insert(没有value)仍然有效。您可以通过将默认的mode 设置为None,使用args.mode is not None 进行上述检查,然后使用if args.mode is None: args.mode = 'insert' 或类似方法来避免这种情况。

    【讨论】:

      【解决方案2】:

      您的语法更清楚地描述为:

      myprogram {--insert|--update|--delete} value
      

      其中--insert 默认为 True 并且值是必需的。

      argparse 可以让你觉得你想要的语法必须适合它的模型,比如

      if args.insert and (args.update or args.delete):
          parser.print_help()
      

      更明显。

      为回应评论添加:

      这里是伪代码(意思是我没有测试它),它显示了我将如何实现它:

      parser.add_argument('--insert', action='store_true')
      parser.add_argument('--update', action='store_true')
      parser.add_argument('--delete', action='store_true')
      parser.add_argument('value')
      args = parser.parse_args(sys.argv)
      if ((args.insert and args.delete) or
          (args.insert and args.update) or
          (args.update and args.delete)):
          # can't pick more than one, complain and quit 
      elif not (args.update or args.delete):
          # they specified no action so assume insert
          args.insert = True
      
      # now one and only one of insert/update/delete is
      # True and args.value contains the argument
      

      我希望这能让事情更清楚。

      【讨论】:

      • 感谢您的回答,但我没有完全理解您:我确实添加了“--insert”参数并将默认设置为 True。所以,这部分奏效了。但是不带参数调用myprogram 会失败,因为需要value。可能我根本没听懂你……
      • 请使用新代码更新您的问题或打开一个新问题,因为我无法阅读我看不到的内容。我怀疑您试图保留不需要的互斥组。
      • 我已经测试了你的解决方案,用户不能选择-h,因为value是必需的。除此之外,据我了解,这些 if 块完全是在做一个互斥组的工作。
      【解决方案3】:

      使位置参数可选(使用'?')

      parser = ArgumentParser()
      group = parser.add_mutually_exclusive_group()
      group.add_argument('--delete', metavar='value')
      group.add_argument('--update', metavar='value')
      group.add_argument('value', nargs='?')
      

      用法是:

      usage: ipython [-h] [--delete value | --update value | value]
      

      【讨论】:

        猜你喜欢
        • 2016-05-04
        • 2019-02-16
        • 2016-05-24
        • 1970-01-01
        • 2013-04-02
        • 2020-07-29
        • 2013-03-09
        • 2021-08-08
        • 2019-09-13
        相关资源
        最近更新 更多