首页 > 解决方案 > python3中没有为argparse指定子命令时如何显示“参数太少”错误

问题描述

一个示例脚本:

import argparse

def main(args=None):
    parser = argparse.ArgumentParser(prog='PROG')

    subparsers = parser.add_subparsers(help='sub-command help')

    parser_a = subparsers.add_parser('a', help='a help')
    parser_a.add_argument('--foo', choices='ABC', help='foo help')

    parser_b = subparsers.add_parser('b', help='b help')
    parser_b.add_argument('--baz', choices='XYZ', help='baz help')

    args = parser.parse_args(args)

if __name__ == '__main__':
    main()

使用 Python2:

$ python2 test.py
usage: PROG [-h] {a,b} ...
PROG: error: too few arguments

这就是我想要的,当命令行中缺少子命令时,脚本会提示缺少参数的错误,并用简短的使用消息提示我。

但是对于 Python3:

$ python3 test.py
# nothing happens

它不会提示任何有关使用的帮助并静默退出(尽管我可以使用它python3 test.py -h来获取帮助消息)。如何更改代码以使其像 python2 方式一样工作并使其与 Python2 和 Python3 兼容?

所以在 Python2 中,它可以检测到丢失的子命令错误并提前退出,但对于 Python3 则不行。对我来说问题是我有很多代码parser.parse_args(args)依赖于解析的参数,它适用于python2,当我将它迁移到python3时发现这个问题,如果在命令行中没有指定子命令,这些代码会引发错误,我需要一种方法来检测命令行中指定了子命令,并且不应该破坏脚本以在 python2 下运行。

对我来说,一种可能的解决方案是检查解析的“args”是否为空,但这对我不起作用,因为我的脚本有一些全局选项,例如:

parser.add_argument('--go', choices='123', help='global option help')

标签: pythonpython-3.xargparse

解决方案


在 3.7 文档中,子命令部分https://docs.python.org/3/library/argparse.html#sub-commands包括

  • required - 是否必须提供子命令,默认为 False。

早期 v3 版本中缺少此功能,但您可以使用

subparsers.required = True

还要确保包含一个dest='cmd'(或您的选择),以便错误消息可以命名缺少的子解析器命令。

过去需要子解析器(因为在幕后,参数是通常需要的位置)。但是随着 Py3 在测试和报告所需参数的方式上发生了变化,子解析器陷入了困境。所以 Py3 子解析器已经有一段时间不需要了。添加required参数使您可以选择修复它(默认的 False 是对那个尴尬的临时情况表示赞同)。

In [525]:     parser = argparse.ArgumentParser(prog='PROG')
     ...: 
     ...:     subparsers = parser.add_subparsers(help='sub-command help', dest='
     ...: cmd')
     ...:     subparsers.required = True
     ...:     parser_a = subparsers.add_parser('a', help='a help')
     ...:     parser_a.add_argument('--foo', choices='ABC', help='foo help')
     ...: 
     ...:     parser_b = subparsers.add_parser('b', help='b help')
     ...:     parser_b.add_argument('--baz', choices='XYZ', help='baz help')
     ...: 
     ...:     args = parser.parse_args([])
     ...: 
     ...: 
usage: PROG [-h] {a,b} ...
PROG: error: the following arguments are required: cmd

推荐阅读