argparse - 使用特定参数重现“--help”参数的行为

时间:2014-01-12 03:30:20

标签: python linux python-2.7 argparse

使用Python {v2.7的argparse模块时遇到了一些麻烦。 基本上,我所拥有的是一个使用5个必需参数的脚本:

  1. URL
  2. 方法
  3. 登录
  4. 密码
  5. 输出
  6. 语法示例如下所示:

      

    script.py -w / - url [URL] -m / - method [METHOD] -l / - login [LOGIN] -p / - password [PASSWORD] -o / - output [OUTPUT ]

    我想做的是:

    • 添加可选参数-t/--test
    • 它的行为是,根据与-w/--url参数一起使用的网址,它会完全绕过-m/--method-l/--login-p/--password参数,但对于它要工作,我需要告诉argparse在提供-t/--test时停止处理参数(但仅限于-w/--url)。

    这种行为甚至可能吗?我尝试使用argparse子命令,但似乎(至少对我的小知识)有点矫枉过正。

    注意:这是我的原始代码:

    # Description : parses script arguments
    # Argument(s) : all
    # Return value : all arguments values
    def testArgs():
        parser = argparse.ArgumentParser(description='Foo', formatter_class=argparse.RawDescriptionHelpFormatter)
        parser.add_argument('-w','--url', help='URL', required=True)
        parser.add_argument('-t','--test', help='Test command', action='store_true')
        parser.add_argument('-m','--method', help='METHOD', required=True)
        parser.add_argument('-u','--login_name', help='LOGIN', required=True)
        parser.add_argument('-p','--login_password', help='PASSWORD', required=True)
        parser.add_argument('-o','--output_format', help='OUTPUT', required=True, choices=['json', 'yaml', 'python'], default='json')
        args = parser.parse_args()
        return args
    

    编辑:经过大量测试后,我完成了以下工作:

    def testArgs():
        parser = argparse.ArgumentParser(description='DESCRIPTION')
        subparsers = parser.add_subparsers()
        p_list = subparsers.add_parser('test', help='List all available methods')
        p_list.add_argument('-w', help='URL', required=True)
        p_list.add_argument('-t', help='Test', action='store_true', required=True)
        p_cmd = subparsers.add_parser('cmd', help='Executes command')
        p_cmd.add_argument('-w', help='URL', required=True)
        p_cmd.add_argument('-m', help='Method', required=True)
        p_cmd.add_argument('-l', help='Login', required=True)
        p_cmd.add_argument('-p', help='Password', required=True)
        p_cmd.add_argument('-o', help='Output', required=True)
        args = parser.parse_args()
        return args
    

    表现出以下行为:

    $ python testArgparse.py -h
    usage: testArgeparse.py [-h] {test,cmd} ...
    
    DESCRIPTION
    
    positional arguments:
      {test,cmd}
        test      Lists all available methods
        cmd       Executes command
    
    optional arguments:
      -h, --help  show this help message and exit
    

    但要获取其他参数的帮助,我需要执行以下操作:

    $ python testArgparse.py test -h
    usage: testArgparse.py test [-h] -w W -t
    
    optional arguments:
      -h, --help  show this help message and exit
      -w W        URL
      -t          Test
    
    
    $ python testArgparse.py cmd -h
    usage: testArgparse.py cmd [-h] -w W -m M -l L -p P -o O
    
    optional arguments:
      -h, --help  show this help message and exit
      -w W        URL
      -m M        Method
      -l L        Login
      -p P        Password
      -o O        Output
    

    我希望能够至少显示所有参数的帮助,而不必对--helptest参数使用cmd

    理想情况下,我喜欢的是这种行为:

    $ python testArgparse.py [-w URL -t] | [-w URL -m METHOD -u LOGIN -p PASS -o OUTPUT]
    

1 个答案:

答案 0 :(得分:1)

带有required=True

store_true没有意义。默认值为False,但如果需要,则返回的值始终为True

由于无条件只需要-w,我会将required参数放在其他所有内容上。然后在parse_args之后测试所需的值。我仍然可以在当时使用argparse错误。换句话说,做我自己的测试,而不是在argparse中尝试一些奇特的东西。

def testArgs():
    usage = '[-w URL -t] | [-w URL -m METHOD -u LOGIN -p PASS -o OUTPUT]'
    parser = argparse.ArgumentParser(description='DESCRIPTION',usage=usage)
    parser.add_argument('-w', help='URL', required=True)
    parser.add_argument('-t', help='Test', action='store_true')
    parser.add_argument('-m', help='Method')
    parser.add_argument('-l', help='Login')
    parser.add_argument('-p', help='Password')
    parser.add_argument('-o', help='Output')
    args = parser.parse_args()

    # sample test, streamline and refine to suit your needs
    # this assumes the default for all these args is None
    if not args.t: # '-t' in in argv
        if any([args.m is None, args.l is None, args.p is None, args.o is None]):
            parser.error('m,l,p,o are all required')
    return args

1216:~/mypy$ python2.7 stack21070971.py
usage: [-w URL -t] | [-w URL -m METHOD -u LOGIN -p PASS -o OUTPUT]
stack21070971.py: error: argument -w is required

1213:~/mypy$ python2.7 stack21070971.py -w url
usage: [-w URL -t] | [-w URL -m METHOD -u LOGIN -p PASS -o OUTPUT]
stack21070971.py: error: m,l,p,o are all required

1213:~/mypy$ python2.7 stack21070971.py -w url -t
Namespace(l=None, m=None, o=None, p=None, t=True, w='url')

1214:~/mypy$ python2.7 stack21070971.py -w url -m mmm
usage: [-w URL -t] | [-w URL -m METHOD -u LOGIN -p PASS -o OUTPUT]
stack21070971.py: error: m,l,p,o are all required
...

1215:~/mypy$ python2.7 stack21070971.py -w url -m mmm -l uuu -p ppp -o ooo
Namespace(l='uuu', m='mmm', o='ooo', p='ppp', t=False, w='url')