如何在python中编写argparse组合选项

时间:2011-04-09 06:45:09

标签: python argparse

我对这件小活动感到困扰。我做了一些实验,但未能达到效果。

要求:

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

用法或规则:

  1. -c(比较)需要2个参数。

    -v(verify)需要1个参数。

    这两者中的必须存在,但不能同时存在

  2. -f是必需参数(输出文件名)。
  3. 输出

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

    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()
    

3 个答案:

答案 0 :(得分:21)

将文件名设置为位置参数,并让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

答案 1 :(得分:7)

您正在寻找什么样的输出?我不知道在--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”)。 / p>

答案 2 :(得分:2)

我认为基本投诉是默认的positional argumentsoptional 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方法。