【问题标题】:argparse: how to configure multiple choice, multiple value, optional argument?argparse:如何配置多项选择,多值,可选参数?
【发布时间】:2022-01-19 01:07:33
【问题描述】:

我正在尝试设置一个参数,该参数从给定的选项列表中接受一个或多个值,但不是强制性的。我正在尝试这个(有几个变种也不能按预期工作):

parser.add_argument("FLAGS", nargs='*', choices=["X","Y","Z","ALL"])

我希望从选项列表中获得一个值列表,或者如果没有给出任何内容,则获得一个空列表(我认为应该由nargs='*' 强制执行)。但无论我是否添加default="",当我不传递任何参数时,它都会失败:

error: argument FLAGS: invalid choice: []

如何实现我所需要的?

【问题讨论】:

    标签: python argparse


    【解决方案1】:

    这可能不符合您的需求,但您可以使用--flags 之类的选项轻松完成。

    parser.add_argument(
        "--flags",
        nargs='*',
        default=[],  # Instead of "None"
        choices=["X", "Y", "Z", "ALL"])
    
    args = parser.parse_args()
    print(args)
    
    $ tmp.py
    Namespace(flags=[])
    
    $ tmp.py --flags
    Namespace(flags=[])
    
    $ tmp.py --flags X
    Namespace(flags=['X'])
    
    $ tmp.py --flags X Z
    Namespace(flags=['X', 'Z'])
    
    $ tmp.py --flags foobar
    usage: tmp.py [-h] [--flags [{X,Y,Z,ALL} ...]]
    tmp.py: error: argument --flags: invalid choice: 'foobar' (choose from 'X', 'Y', 'Z', 'ALL')
    
    $ tmp.py --help
    usage: tmp.py [-h] [--flags [{X,Y,Z,ALL} ...]]
    
    optional arguments:
      -h, --help            show this help message and exit
      --flags [{X,Y,Z,ALL} ...]
    

    【讨论】:

      【解决方案2】:

      位置“*”得到一些特殊处理。它的nargs 对空列表(无)感到满意。它总是被处理。对照choices 检查一个空的字符串列表是什么意思?

      所以get_values() 方法可以:

          # when nargs='*' on a positional, if there were no command-line
          # args, use the default if it is anything other than None
          elif (not arg_strings and action.nargs == ZERO_OR_MORE and
                not action.option_strings):
              if action.default is not None:
                  value = action.default
              else:
                  value = arg_strings
              self._check_value(action, value)
      

      其中_check_value 测试value 是否在choices 中。

      这样的位置最好与有效的default 一起使用。

      In [729]: p=argparse.ArgumentParser()
      In [730]: a=p.add_argument("FLAGS", nargs='*', choices=["X","Y","Z","ALL"])
      In [731]: p.parse_args([])
      usage: ipython3 [-h] [{X,Y,Z,ALL} [{X,Y,Z,ALL} ...]]
      ipython3: error: argument FLAGS: invalid choice: [] (choose from 'X', 'Y', 'Z', 'ALL')
      ...
      

      针对choices 测试空列表失败:

      In [732]: a.choices
      Out[732]: ['X', 'Y', 'Z', 'ALL']
      In [733]: [] in a.choices
      Out[733]: False
      In [734]: 'X' in a.choices
      Out[734]: True
      

      如果我们设置一个有效的默认值:

      In [735]: a.default='X'
      In [736]: p.parse_args([])
      Out[736]: Namespace(FLAGS='X')
      

      这种行为是允许我们在mutually_exclusive_group 中使用这种定位的部分原因。

      如果您不想指定有效的默认值,则将其更改为标记参数可以避免问题。

      【讨论】:

        猜你喜欢
        • 2015-12-11
        • 2018-03-04
        • 2019-04-13
        • 2021-12-13
        • 2011-05-27
        • 1970-01-01
        • 2011-11-20
        相关资源
        最近更新 更多