argparse未正确处理子parser中的缩写

2024-09-30 04:33:30 发布

您现在位置:Python中文网/ 问答频道 /正文

(运行在python3.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名称/别名时出现问题。在

代码如下:

^{pr2}$

因此,根据上述规范,应接受以下任何一项:

- "Caesar" or "caesar"
- "C" or "c" 
- Any abbreviation in between "c" and "caesar" 

所以问题是:

这是有效的:$ python prog.py c 123O

这将产生一个错误:$ python prog.py caes 123X

prog.py: error: invalid choice: 'cae' (choose from 'caesar', 'c')

现在是令人困惑的部分。在

根据argparse文档

ArgumentParser supports the creation of such sub-commands with the add_subparsers() method. The add_subparsers() method is normally called with no arguments and returns a special action object. This object has a single method, add_parser(), which takes a command name and any ArgumentParser constructor arguments, and returns an ArgumentParser object that can be modified as usual.

  1. 好的,那么任何object created with add_subparser()都可以用object.add_parser()创建自己的{},对吗?

  2. …这意味着这个新创建的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)

Create a new ArgumentParser object. All parameters should be passed as keyword arguments. Each parameter has its own more detailed description below, but in short they are:

allow_abbrev - Allows long options to be abbreviated if the abbreviation is unambiguous.

(default: True)

Changed in version 3.5: allow_abbrev parameter was added.

(this was on python 3.6.0)


先谢谢你们,伙计们


Tags: andpynoneaddtrueparserobjectargparse
2条回答

实现了一个允许使用子方名称缩写的补丁,但是当它被证明是有缺陷的时候,它就被撤销了:

Issue 12713: allow abbreviation of sub commands by users

允许用户关闭长选项的缩写是另一个问题,在中处理

Issue 14910: argparse: disable abbreviation

代码的两个不同部分。在

allow_abbrev - Allows long options to be abbreviated if the abbreviation is unambiguous.

长选项的创建方式如下:

caesar.add_argument('-f',' foobar')

使用默认的allow_abbrev值,这将与'-f'、'foo'和'foobar'一起使用。本例中的long_option是'foobar'。有了它,False,'foo'就不起作用了。在

parser决定c或{}或{}是否是有效的子parser命令(通过subp,由parser.add_subparsers创建的特殊操作对象)。它的行为更像是带有choices的位置。在

^{pr2}$

我得到的错误是:

usage: [-h] {caesar,c} ...
: error: unrecognized arguments: a e s

暗示缩写应该是可组合的,即两个不同的缩写“c”和“a”可以通过传递ca来引用。在

那到底会发生什么?ca既是c和(不存在的)a缩写的组合,也是缩写。解析器应该选择哪个?因此,在设计库时,必须明确地解决这个问题:为了可预测性,您不能两者兼得。在

也就是说,也许你可以通过传递conflict_handler='resolve'来调整结果?https://docs.python.org/3/library/argparse.html#allow-abbrev

相关问题 更多 >

    热门问题