Python argparse未正确处理子Parser中的缩写

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

(在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 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对象,可以像往常一样修改

  • 好的,那么使用add_subparser()创建的任何
    对象都可以使用
    对象创建自己的
    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'))
    。这里的问题是应该可以组合短命令行标志。与POSIX
    getopt.h
    完全相同,想想
    tr-cd
    grep-vERF
    ,或者著名的
    tar xvzf
    。可以组合短选项,就像在
    python prog.py-caes
    中一样。但这不适用于子命令行ds。只有一个“词”起作用。感谢您的全面回复!这绝对比试图找出医生好。
    caesar.add_argument('-f','--foobar')
    
    parser.add_argument('foo', choices = ['c', 'caesar'])