【问题标题】:How to code argparse combinational options in python如何在 python 中编写 argparse 组合选项
【发布时间】:2011-08-01 23:32:44
【问题描述】:

我一直对要完成的这一小块活动感到困扰。我确实做了一些实验,但无法达到结果。

要求:

   test2.py [-c/-v] -f

用法或规则:

  1. -c(比较)接受2个参数。

    -v(验证)采用 1 个参数。

    其中一个必须存在,但不能同时存在。

  2. -f 是强制参数(输出文件名)。

输出:

我能够得到所需的输出,如下所示

kp@kp:~/Study/scripts$ ./test.py -c P1 P2 -f p
kp@kp:~/Study/scripts$ ./test.py -v P1 -f p
kp@kp:~/Study/scripts$ ./test.py -v P1 
usage: test.py <functional argument> <ouput target argument>
test.py: error: argument -f/--file is required
kp@kp:~/Study/scripts$ ./test.py -c P1 P2 
usage: test.py <functional argument> <ouput target argument>
test.py: error: argument -f/--file is required
kp@kp:~/Study/scripts$ 

问题是:

当你使用时,test.py -h,
1. 输出不会表明 -c/-v 其中一个是强制性的,但不是两个都是强制性的。它表示所有参数都是可选的。
2. 输出将指示可选参数下的-f 选项不正确。 -f 是强制参数,我想在外面显示 - 可选参数。

如何更改脚本以使 -h 选项输出对用户更友好(无需任何外部验证)

usage: test.py <functional argument> <ouput target argument>

Package Compare/Verifier tool.

optional arguments:
  -h, --help            show this help message and exit
  -f outFileName, --file outFileName
                        File Name where result is stored.
  -c Package1 Package2, --compare Package1 Package2
                        Compare two packages.
  -v Package, --verify Package
                        Verify Content of package.
kiran@kiran-laptop:~/Study/scripts$ 

代码:

我正在使用下面的代码来实现输出,

#!/usr/bin/python

import sys
import argparse

def main():
    usage='%(prog)s <functional argument> <ouput target argument>'
    description='Package Compare/Verifier tool.'
    parser = argparse.ArgumentParser(usage=usage,description=description)

    parser.add_argument('-f','--file',action='store',nargs=1,dest='outFileName',help='File Name where result is stored.',metavar="outFileName",required=True)


    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument('-c','--compare',action='store',nargs=2,dest='packageInfo',help='Compare two packages.',metavar=("Package1","Package2"))
    group.add_argument('-v','--verify',action='store',nargs=1,dest='packageName',help='Verify Content of package.',metavar='Package')
    args = parser.parse_args()

if __name__ == "__main__":
    main()

【问题讨论】:

  • 除了将-f 替换为位置参数之外,我还将创建compare 和verify 两个子命令,而不是一对互斥的必需选项。 (test.py compare P1 P2 output.txt 和 test.py verify P1 output.txt;请注意,需要为每个子解析器指定位置参数。或者,将 -f 设为默认为标准输出的选项;您可以保留主解析器上的选项,以便它们适用给出了哪个子命令)。

标签: python argparse


【解决方案1】:

将文件名设置为位置参数,并让argparse 设置自己的使用消息:

$ python so.py --help
usage: so.py [-h] [-c Package1 Package2 | -v Package] outFileName

文件名应该是位置的,你应该让argparse写它自己的使用信息。

代码

#!/usr/bin/python

import sys
import argparse

def main():
    description='Package Compare/Verifier tool.'
    parser = argparse.ArgumentParser(description=description,
                                     epilog='--compare and --verify are mutually exclusive')

    parser.add_argument('f',action='store',nargs=1,
                        help='File Name where result is stored.',
                        metavar="outFileName")

    group = parser.add_mutually_exclusive_group(required=False)
    group.add_argument('-c','--compare',action='store',nargs=2,dest='packageInfo',help='Compare two packages.',metavar=("Package1","Package2"))
    group.add_argument('-v','--verify',action='store',nargs=1,dest='packageName',help='Verify Content of package.',metavar='Package')

    args = parser.parse_args()

if __name__ == "__main__":
    main()

帮助信息

$ python so.py --help
usage: so.py [-h] [-c Package1 Package2 | -v Package] outFileName

Package Compare/Verifier tool.

positional arguments:
  outFileName           File Name where result is stored.

optional arguments:
  -h, --help            show this help message and exit
  -c Package1 Package2, --compare Package1 Package2
                        Compare two packages.
  -v Package, --verify Package
                        Verify Content of package.

--compare and --verify are mutually exclusive

【讨论】:

  • 这很接近,但从技术上讲,我需要 -f 帮助文件中的可选参数。因为标题“可选参数:”具有误导性,当 -f 是强制参数时。
  • 更新了我的答案,文件现在是一个位置参数。
  • @Matan,但使用更改后的代码 - python so.py out.txt 有效。这是不正确的 - 因为 -c/-v (其中一个必须存在)。
  • 如果你设置了required=True 会解决问题吗?
【解决方案2】:

您正在寻找什么确切的输出?我不知道在 --help 输出中表示互斥性的任何标准语法,如果你编造一个,它可能会让你的用户感到困惑。另外我假设 argparse 不支持它的语法(因为如果支持,它已经可以工作了)。

我建议您保持简单,只需向您的用户解释每个参数的帮助中的互斥。所以改变他们的帮助字符串如下:

-c Package1 Package2, --compare Package1 Package2
                      Compare two packages (may not be used with -v).
-v Package, --verify Package
                      Verify Content of package (may not be used with -c).

这是非常明显且相当简洁的。

另一种选择是不提它,并让用户通过尝试同时使用它们来发现它们是互斥的(argparse 会自动生成一个用户友好的错误,例如“PROG: error: argument -c: not allowed with argument -v”)。

【讨论】:

  • 等待一周后没有得到正确回复 您的回复似乎是最实用的。貌似没有其他技术解决方法。
【解决方案3】:

我认为基本的抱怨是默认的positional arguments 和optional arguements 组名。在help中,optional arguments表示:requires a flag like -f or --file; positional arguments 表示 it is identified by position。对于默认值,positionals 确实是必需的,optionals 确实是可选的(不是必需的)。但是用户可以使用required 属性来更改它,这会导致术语混乱。

解决此问题的一种方法是定义您自己的参数组。这些组影响help 的布局,但对解析没有影响。它们也不影响usage 行。

def main():
    description='Package Compare/Verifier tool.'
    parser = argparse.ArgumentParser(usage=None,description=description)

    maingroup = parser.add_argument_group(title='required')
    maingroup.add_argument('-f','--file',nargs=1,dest='outFileName',help='File Name where result is stored.',metavar="outFileName",required=True)
    exgroup = parser.add_argument_group(title='one or the other')

    group = exgroup.add_mutually_exclusive_group(required=True)
    group.add_argument('-c','--compare',nargs=2,dest='packageInfo',help='Compare two packages.',metavar=("Package1","Package2"))
    group.add_argument('-v','--verify',nargs=1,dest='packageName',help='Verify Content of package.',metavar='Package')
    args = parser.parse_args()

产生:

usage: stack5603364.py [-h] -f outFileName (-c Package1 Package2 | -v Package)

Package Compare/Verifier tool.

optional arguments:
  -h, --help            show this help message and exit

required:
  -f outFileName, --file outFileName
                        File Name where result is stored.

one or the other:
  -c Package1 Package2, --compare Package1 Package2
                        Compare two packages.
  -v Package, --verify Package
                        Verify Content of package.

mutually_exclusive_group 仅影响 usage 行。

(-c Package1 Package2 | -v Package)

显示需要其中一个选项的组。

[-c Package1 Package2 | -v Package]

将是一个可选组。 [] 用于标记可选(在“不需要”的意义上)参数。注意-h 是如何继续被标记的。

http://bugs.python.org/issue9694 是相关的 Python 问题,argparse 作者偏爱这种argument_group 方法。

【讨论】:

    猜你喜欢
    • 2016-06-21
    • 1970-01-01
    • 2016-10-22
    • 1970-01-01
    • 1970-01-01
    • 2020-01-11
    • 2018-03-26
    • 2016-08-11
    • 2013-07-06
    相关资源
    最近更新 更多