【问题标题】:Python argparse - mandatory argument - either positional or optionalPython argparse - 强制参数 - 位置或可选
【发布时间】:2018-04-29 01:22:00
【问题描述】:

我希望用户能够将强制参数传递给“argparse”,可以是位置参数,也可以是可选参数。

即, 以下两种形式均有效:

my_prog arg
my_prog -m arg

我见过Argparse optional positional arguments?

但是那里的建议使 both 形式可选。我希望其中一个是强制性的。

当然,我可以在解析其中至少一个已设置后添加手动检查。但我有一种预感,一定有更好的解决方案。

(即使使用我的手动方法,“帮助”部分也将它们都显示为可选)

【问题讨论】:

    标签: python argparse


    【解决方案1】:

    mutually exclusive group 机制可以采用required 参数。它还可以与一个 ? 位置以及可选参数(标记参数)一起使用。 (多个 '?' 位置没有意义)。

    help 显示有 2 个默认组,positonaloptional。因此,即使 optional(已标记)设置为 required,默认情况下也会显示在 optional 组中。 usage 行是关于是否需要参数的更好指南。如果您不喜欢帮助部分中的组标签,请定义您自己的参数组。

    In [146]: import argparse
    In [147]: parser = argparse.ArgumentParser()
    In [148]: gp = parser.add_mutually_exclusive_group(required=True)
    In [149]: gp.add_argument('pos', nargs='?', default='foo');
    In [150]: gp.add_argument('-f','--foo', default='bar');
    
    In [151]: parser.parse_args('arg'.split())
    Out[151]: Namespace(foo='bar', pos='arg')
    
    In [152]: parser.parse_args('-f arg'.split())
    Out[152]: Namespace(foo='arg', pos='foo')
    
    In [153]: parser.parse_args('arg -f arg'.split())
    usage: ipython3 [-h] [-f FOO] [pos]
    ipython3: error: argument -f/--foo: not allowed with argument pos
    
    In [154]: parser.parse_args(''.split())
    usage: ipython3 [-h] [-f FOO] [pos]
    ipython3: error: one of the arguments pos -f/--foo is required
    
    
    In [155]: parser.parse_args('-h'.split())
    usage: ipython3 [-h] [-f FOO] [pos]
    
    positional arguments:
      pos
    
    optional arguments:
      -h, --help         show this help message and exit
      -f FOO, --foo FOO
    

    糟糕,使用情况未在互斥组中显示 -fpos。有时usage 格式很脆弱。

    切换定义参数的顺序可以更好地使用

    In [156]: parser = argparse.ArgumentParser()
    In [157]: gp = parser.add_mutually_exclusive_group(required=True)
    In [158]: gp.add_argument('-f','--foo', default='bar');
    In [159]: gp.add_argument('pos', nargs='?', default='foo');
    In [160]: 
    In [160]: parser.parse_args('-h'.split())
    usage: ipython3 [-h] (-f FOO | pos)
    
    positional arguments:
      pos
    
    optional arguments:
      -h, --help         show this help message and exit
      -f FOO, --foo FOO
    

    使用用户定义的参数组:

    In [165]: parser = argparse.ArgumentParser()
    In [166]: gp = parser.add_argument_group('Mutually exclusive')
    In [167]: gpm = gp.add_mutually_exclusive_group(required=True)
    In [168]: gpm.add_argument('-f','--foo', default='bar');
    In [169]: gpm.add_argument('pos', nargs='?', default='foo');
    In [170]: 
    In [170]: parser.parse_args('-h'.split())
    usage: ipython3 [-h] (-f FOO | pos)
    
    optional arguments:
      -h, --help         show this help message and exit
    
    Mutually exclusive:
      -f FOO, --foo FOO
      pos
    

    这是一般规则的一个例外,argument_groups 和mutual_exclusive_groups 不是为嵌套而设计的。

    m-x-group 不是必需的,用法将使用[]

    usage: ipython3 [-h] [-f FOO | pos]
    

    【讨论】:

    • 太棒了。只有一个警告:这些组定义必须在所有其他常规参数之后,否则它不会在帮助中显示漂亮的(-f FOO | pos)
    • 是的,有两件事会影响usage。位置显示在可选项之后,并且仅当其参数与该顺序匹配时才会显示组。纠正这种脆弱性需要对使用格式化程序进行重大重写。
    猜你喜欢
    • 2014-04-15
    • 2014-09-09
    • 2011-05-27
    • 2012-08-14
    • 2013-01-28
    • 2018-02-20
    • 2019-04-13
    相关资源
    最近更新 更多