(运行在Python 3.6.0)
简短概括
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')
为什么即使使用了
allow_abbrev=True
,subparser
的缩写仍然无效?
详细说明
实际上,我在让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 123
O但这个会出错:
$ python prog.py caes 123
Xprog.py: error: invalid choice: 'cae' (choose from 'caesar', 'c')
现在是令人困惑的部分。
根据 argparse 文档:
ArgumentParser 支持使用 add_subparsers() 方法创建这种子命令。add_subparsers() 方法通常不带参数调用,并返回一个特殊的 Action 对象。该对象有一个方法 add_parser(),它接受一个命令名称和任何 ArgumentParser 构造函数参数,并返回一个 ArgumentParser 对象,可以像通常一样进行修改。
1. 好的,那么使用 add_subparser() 创建的任何对象都可以使用 object.add_parser() 创建自己的 ArgumentParser 对象,对吧? 2. ……这意味着这个新创建的 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
- 如果缩写不会引起歧义,则允许长选项被缩写。(默认值:True)
在3.5版本中发生了更改:添加了allow_abbrev参数。
(这是在Python 3.6.0上)