Python 2.7 argparse:如何正确嵌套可选的mutally独占参数?

时间:2013-05-28 10:28:32

标签: python python-2.7 command-line-arguments argparse

我的程序应包含以下选项,由argparse正确解析:

  1. 纯粹是可选的:[-h, --help][-v, --version]
  2. 互斥:[-f FILE, --file FILE][-u URL, --url URL]
  3. 如果选择了--url,则可选:[-V, --verbose]
  4. 如果选择了--file--url,则需要
  5. [-F, --format FORMAT]
  6. 所需的使用模式为:

    prog.py [-h] [-v] [-f FILE (-F FORMAT) | -u URL [-V] (-F FORMAT) ]
    

    -F要求适用于互斥组的两个成员 不确定它是否是positional

    所以应该可以运行:

    prog.py -u "http://foo.bar" -V -F csv
    

    并且解析器尖叫,以防我忘记-F(正如他应该的那样)。

    到目前为止我做了什么:

    parser = ArgumentParser(decription='foo')
    
    group = parser.add_mutually_exclusive_group()    
    group.add_argument('-f','--file', nargs=1, type=str, help='')
    group.add_argument('-u','--url', nargs=1, type=str, help='')    
    
    parser.add_argument('-V','--verbose', action='store_true', default=False, help='')
    parser.add_argument('-F','--format', nargs=1, type=str, help='')
    

    由于它在没有命令行参数的情况下运行“vanilla模式”,因此所有参数都必须是可选的。

    如何在我的代码中实现第3点和第4点?

    编辑:
    我尝试-f-u作为子分析符,如here所述,但子命令似乎被视为位置,如果我在没有参数的情况下运行它,解析器会给我一个error: too few arguments

2 个答案:

答案 0 :(得分:5)

使用nargs = 2和元组metavar近似于你的目标

parser = argparse.ArgumentParser(prog='PROG')
group = parser.add_mutually_exclusive_group()
group.add_argument('-f','--file', nargs=2, metavar=('FILE','FORMAT'))
group.add_argument('-u','--url', nargs=2, metavar=('URL','FORMAT'))
parser.add_argument('-V','--verbose', action='store_true',help='optional with url')

产生:

usage: PROG [-h] [-f FILE FORMAT | -u URL FORMAT] [-V]

optional arguments:
  -h, --help            show this help message and exit
  -f FILE FORMAT, --file FILE FORMAT
  -u URL FORMAT, --url URL FORMAT
  -V, --verbose         optional with url

这需要格式以及文件名或网址,它不需要-F。正如其他人所指出的-V案例中可以忽略-f


  

我尝试使用-f和-u作为subparsers,如此处所述,但是子命令似乎被视为位置,并且解析器给我一个错误:如果我在没有参数的情况下运行它,则参数太少。

在最新版本中,子命令不再被视为必需的位置。据我所知,这是更改错误消息的副作用,以提供更多信息。而不是_parse_known_args做一个:

    if positionals:
        self.error(_('too few arguments'))

它会扫描_actions以查看哪些是必需的,然后在错误消息中按名称列出它们。这在http://bugs.python.org/issue9253中讨论。我知道这个变化正在开发中(3.4),也可能在3.3中。


答案 1 :(得分:2)

当存在特定选项时,可以使用callback方法在optparse中强制执行这些点。

但是,在argparse中,这些不可用。

您可以为urlfile子选项添加subparser,然后单独解析这些选项。 来自帮助:

  

请注意,parse_args()返回的对象只包含其属性   命令行选择的主解析器和子解析器   (而不是任何其他子分子)。所以在上面的例子中,当a命令时   指定时,只有foo和bar属性存在,并且当b命令时   如果指定,则仅存在foo和baz属性。

但我会恰当地记录用法,只是忽略那些没有的论据 适用。

e.g。让这两个命令行的行为完全相同:

prog.py -f FILE -V
prog.py -f FILE