python - 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')
解决方案
在 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
推荐阅读
- xml - XSLT 将来自多个节点的属性连接成单个值
- angular - 如何刷新 AG-GRID 中设置的过滤器值
- amazon-web-services - 自动删除具有给定扩展名且早于某个日期的某些 s3 对象
- javascript - 如何在 express 上设置 preact-render-to-string
- python - model.apply(x) 结果的 xgboost 总和不等于 model.predict(x)
- node.js - 未找到从单端口端点服务的反应和节点 js
- html - 模态引导响应
- typescript - 是否可以在 TypeScript 中为 tsc 编译引发自定义错误?
- java - B 不能转换为 org.apache.shiro.session.Session
- ruby-on-rails - 向 super 的调用添加额外的参数