Python argparse未正确处理子Parser中的缩写
(在python 3.6.0上运行) TL;DR 为什么Python argparse未正确处理子Parser中的缩写,python,argparse,case-sensitive,case-insensitive,subparsers,Python,Argparse,Case Sensitive,Case Insensitive,Subparsers,(在python 3.6.0上运行) TL;DR 为什么subparser缩写即使使用allow_abbrev=True也无效 长版本 基本上,在获取argparse以接受缩写的子parser名称/别名时遇到问题 代码如下: Usage: prog.py [caesar] [key] import sys, argparse def main(argv): parser = argparse.ArgumentParser (description="runs text t
subparser
缩写即使使用allow_abbrev=True
也无效
长版本 基本上,在获取
argparse
以接受缩写的子parser
名称/别名时遇到问题
代码如下:
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)
问题是:
这是有效的:$python prog.py c 123
O
这会给出一个错误:$python prog.py caes 123
X
prog.py: error: invalid choice: 'cae' (choose from 'caesar', 'c')
现在是令人困惑的部分
根据argparse doc:
ArgumentParser支持使用
添加_subparsers()方法。add_subparsers()方法通常是
不带参数调用并返回特殊操作对象。这
对象有一个方法,add_parser(),该方法采用命令名
和任何ArgumentParser构造函数参数,并且返回
ArgumentParser对象,可以像往常一样修改
对象都可以使用对象创建自己的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上实现的)
提前谢谢,伙计们我得到的错误是:
usage: [-h] {caesar,c} ...
: error: unrecognized arguments: a e s
暗示缩写应该是可组合的,因为通过传递ca
可以引用两个不同的缩写“c”和“a”
那里到底应该发生什么ca
是c
和(不存在的)a
缩写形式以及缩写形式的组合。解析器应该选择哪一种?因此,在设计库时必须明确地解决这个问题:为了可预测性,您不能两者兼得
也就是说,您可以通过传递
conflict\u handler='resolve'
来调整结果 实现了一个允许子parser名称缩写的补丁,但当它被证明有缺陷时,就被撤销了:
允许用户关闭长选项的缩写是另一个问题,在中处理
代码的两个不同部分
allow_abbrev-如果缩写明确,则允许缩写long选项
长选项是通过以下方式创建的:
caesar.add_argument('-f','--foobar')
使用默认的allow_abbrev
值,这将与'-f'、'-foo'和'-foobar'一起工作。本例中的long\u选项是'--foobar'。如果使用它False
,“--foo”将不起作用
主要的parser
决定c
或caesar
或cae
是否是有效的子parser命令(通过subp
,由parser.add\u子parser创建的特殊操作对象)。这更像是带有选项的位置
parser.add_argument('foo', choices = ['c', 'caesar'])
缩写参数适用于解析器的标记参数,而不是调用子解析器的名称或别名。3.6真正增加的是关闭它的功能。早期版本总是接受abbrev。但它从未应用于参数选择
,只应用于--foo
类标志。你给解析器什么parser.parse_args(list('caes'))
?看起来argv
列表是['c'、'a'、'e'、's']
。实际上,我说的是parser.parse_args(['caes'))
。这里的问题是应该可以组合短命令行标志。与POSIXgetopt.h
完全相同,想想tr-cd
,grep-vERF
,或者著名的tar xvzf
。可以组合短选项,就像在python prog.py-caes
中一样。但这不适用于子命令行ds。只有一个“词”起作用。感谢您的全面回复!这绝对比试图找出医生好。
caesar.add_argument('-f','--foobar')
parser.add_argument('foo', choices = ['c', 'caesar'])