【问题标题】:argparse - Reproduce behavior of "--help" argument with a specific argumentargparse - 使用特定参数重现“--help”参数的行为
【发布时间】:2014-01-30 23:59:20
【问题描述】:

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

  1. 网址
  2. 方法
  3. 登录
  4. 密码
  5. 输出

语法示例如下所示:

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

我想做的是:

  • 添加可选参数-t/--test
  • 它的行为是,基于与-w/--url 参数一起使用的url,它会完全绕过-m/--method-l/--login-p/--password 参数但是,为了让它工作,我需要告诉@如果提供了-t/--test,则987654328@ 停止处理参数(但仅限-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

我希望至少能够显示有关所有参数的帮助,而不必为 testcmd 参数使用 --help

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

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

【问题讨论】:

  • 看到-t/--test时忽略其他参数
  • 将原始代码添加到第一条评论。
  • 您应该查看mutually exclusive groups。您可以使一个参数或另一个参数是必需的,但不是两者都需要。不过,您可能需要做一些诡计才能拥有 1 个 3 个组。
  • 所以如果'-t',其他参数('mupo')就不再需要了。你不想忽略它们。那正确吗?首先,我会删除“必需”标志,为它们提供有意义的默认值,并在 parse_args 之后测试是否存在必要的值。
  • 将我这边更多测试的结果添加到原帖中。

标签: python linux python-2.7 argparse


【解决方案1】:

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

【讨论】:

  • 再次感谢 hpaulj。我最终使用了您的建议并测试了 args 的内容。我被告知停止使用sys.argv 来检查参数并改用argparse,但似乎在某些情况下你必须解决这个问题。
猜你喜欢
  • 2013-03-28
  • 2013-09-21
  • 2019-03-12
  • 1970-01-01
  • 2022-01-26
  • 2020-05-08
  • 2015-10-17
  • 2017-02-24
  • 2021-10-16
相关资源
最近更新 更多