【发布时间】:2018-04-23 15:40:15
【问题描述】:
(在 python 3.6.0 上运行)
TL;DR
Usage: prog.py {caesar | vigenere} [key]
parser = argparse.ArgumentParser()
subp = parser.add_subparsers()
caesar = subp.add_parser("caesar", aliases=["c"], allow_abbrev=True)
args = parser.parse_args()
$ python prog.py caes 123
prog.py: error: invalid choice: 'caes' (choose from 'caesar', 'c')
为什么subparser的缩写即使是allow_abbrev=True也是无效的?
长版
基本上,让argparse 接受缩写的subparsers 名称/别名时遇到问题。
代码如下:
Usage: prog.py [caesar] [key]
import sys, argparse
def main(argv):
parser = argparse.ArgumentParser
(description="runs text through X cipher")
subp = parser.add_subparsers\
(help="sub-command help")
#<ArgumentParser object>
caesar = subp.add_parser\
("caesar", aliases=["c"], allow_abbrev=True)
caesar.add_argument\
("key", metavar = "key (any integer)",\
type = int, default = 0)
args = parser.parse_args()
print(caesar)
if __name__ == "__main__":
sys.argv = list(str(c).lower() for c in sys.argv[0:])
main(sys.argv)
所以从上面的代码来看,应该可以接受以下任何一项:
- "Caesar" or "caesar"
- "C" or "c"
- Any abbreviation in between "c" and "caesar"
那么问题来了:
这有效:$ python prog.py c 123O
这给出了一个错误:$ python prog.py caes 123 X
prog.py: error: invalid choice: 'cae' (choose from 'caesar', 'c')
现在是令人困惑的部分。
根据 argparse 文档:
ArgumentParser 支持使用 add_subparsers() 方法。 add_subparsers() 方法通常是 不带参数调用并返回一个特殊的操作对象。这 object 有一个方法,add_parser(),它接受一个命令名 和任何 ArgumentParser 构造函数参数,并且 返回一个 可以照常修改的 ArgumentParser 对象。
好的,所以任何
object created with add_subparser()都可以创建自己的ArgumentParser object和object.add_parser()对吧?...这意味着这个新创建的
ArgumentParser对象应该能够接受任何ArgumentParser参数是吗?
ArgumentParser 定义:
class
argparse.ArgumentParser(
prog=None, usage=None,
description=None, epilog=None,
parents=[],formatter_class=argparse.HelpFormatter,
prefix_chars='-',fromfile_prefix_chars=None,
argument_default=None,conflict_handler='error',
add_help=True, allow_abbrev=True)
创建一个新的 ArgumentParser 对象。所有参数都应作为关键字传递 论据。每个参数在下面都有自己更详细的描述,但总之 他们是:
allow_abbrev- 如果缩写明确,则允许缩写长选项。(默认:真)
3.5 版更改:添加了 allow_abbrev 参数。
(这是在 python 3.6.0 上)
提前谢谢各位
【问题讨论】:
-
缩写参数适用于解析器的标记参数,而不适用于调用子解析器的名称或别名。
-
请注意,allow_abbrev 默认为 true。 3.6 中真正添加的是关闭它的能力。早期版本总是接受缩写。但它从未应用于参数
choices,仅应用于--foo之类的标志。
标签: python argparse case-sensitive case-insensitive subparsers