12

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

  1. 纯可选:[-h, --help][-v, --version]
  2. 互斥:[-f FILE, --file FILE][-u URL, --url URL]
  3. 如果--url选择了可选:[-V, --verbose]
  4. 如果选择--file--url,则需要:[-F, --format FORMAT]

所需的使用模式将是:

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

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

所以应该可以运行:

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='')

由于它具有无需命令行参数即可运行的“香草模式”,因此所有参数都必须是可选的。

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

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

4

2 回答 2

5

使用 nargs=2 和元组元变量接近您的目标

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

这需要格式以及文件名或 url,它只是不需要-F. 正如其他人指出的那样-V,在这种情况下可以忽略不计-f


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

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

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

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


于 2013-07-26T03:07:01.347 回答
2

当存在某个选项时,可以optparse使用回调方法强制执行这些点。

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

您可以 为和子选项添加一个子解析器,并分别解析它们。从帮助:urlfile

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

但我会正确记录用法,而忽略不适用的论点。

例如,让这两个命令行的行为完全相同:

prog.py -f FILE -V
prog.py -f FILE
于 2013-05-30T12:21:56.300 回答