argparse:当存在子解析器时如何分离未知(和可选)参数.(子解析器也是可选的) [英] argparse: How to separate unknown(and optional) args when subparsers are present.(subparsers are also optional)

查看:21
本文介绍了argparse:当存在子解析器时如何分离未知(和可选)参数.(子解析器也是可选的)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码

parser = argparse.ArgumentParser(allow_abbrev=False, add_help=False)
parser.add_argument('--conf', nargs=1)
parser.add_argument('-h', '--help', nargs='?', const='generic')
parser.add_argument('-v', '--version', action="store_true")

subparsers = parser.add_subparsers()
subparsers.required = False
parser_start = subparsers.add_parser('start')
group1 = parser_start.add_mutually_exclusive_group()
group1.add_argument('--quiet', action="store_true")
group1.add_argument('-V', '--verbose', nargs="*")

# parser_console = subparsers.add_parser('console')

print(argv)
parsed_args = parser.parse_known_args(argv)

现在,当我将 argv 作为 argv = ['abc', 'def']argv = ['abc'] 传递时

Now, when I pass argv as argv = ['abc', 'def'] or argv = ['abc']

我明白

['abc', 'def']
usage: lbrynet [--conf CONF] [-h [HELP]] [-v] {start} ...
lbrynet: error: invalid choice: 'abc' (choose from 'start')

我期待的是在元组中为未知参数获取 ['abc', 'def'] .我检查了很多 stackoverflow 的答案(例如 ans 1, ans 2, ans 3, ans 4) 和错误报告(例如 br1) 和 lot 但我似乎找不到办法做到这一点.这是一个未解决的错误吗?我期望可以做到这一点是错误的.如果无法做到这一点,是否有任何解决方法可以做到这一点?

What I was expecting was to get ['abc', 'def'] in the tuple for unknown args. I've checked a lot of stackoverflow answers(such as ans 1, ans 2, ans 3, ans 4) and bug reports(e.g. br 1) and a lot but I can't seem to find a way to do it. Is this an unsolved bug? Am I wrong in expecting that this can be done. If this can't be done are there any workarounds to doing this?

另外澄清一下,从元组中得到的 ['abc', 'def'] 必须传递给其他一些函数来处理.

Also to clarify, the ['abc', 'def'] got from the tuple have to be passed to some other function to be processed.

很高兴提供任何进一步的说明和/或消除任何歧义.

Happy to provide any further clarifications and/or clear any ambiguities.

推荐答案

正如我在评论中所写,子解析器是一个位置参数.

As I wrote in a comment, subparsers is a positional argument.

用一个简单的位置来说明:

To illustrate with a plain positional:

In [307]: parser = argparse.ArgumentParser()
In [308]: a1 = parser.add_argument('foo')

In [309]: parser.parse_known_args(['one','two'])
Out[309]: (Namespace(foo='one'), ['two'])

'one' 分配给第一个位置.现在给 foo 选择:

'one' is allocated to the first positional. Now give foo choices:

In [310]: a1.choices = ['bar','test']
In [311]: parser.parse_known_args(['one','two'])
usage: ipython3 [-h] {bar,test}
ipython3: error: argument foo: invalid choice: 'one' (choose from 'bar', 'test')

它仍在尝试将第一个字符串分配给 foo.由于它与choices 不匹配,因此会引发错误.

It is still trying to allocate the first string to foo. Since it doesn't match choices, it raises an error.

In [312]: parser.parse_known_args(['bar','one','two'])
Out[312]: (Namespace(foo='bar'), ['one', 'two'])

字符串是根据位置而不是值分配给位置的.任何值检查,例如类型或选择,都在赋值后完成.

Strings are assigned to positionals based on position, not on value. Any value checking, such as with type or choices is done after assignment.

choices 更改为 type 测试:

Change the choices to a type test:

In [313]: a1.choices = None
In [314]: a1.type = int
In [315]: parser.parse_known_args(['bar','one','two'])
usage: ipython3 [-h] foo
ipython3: error: argument foo: invalid int value: 'bar'

In [316]: parser.parse_known_args(['12','one','two'])
Out[316]: (Namespace(foo=12), ['one', 'two'])

这篇关于argparse:当存在子解析器时如何分离未知(和可选)参数.(子解析器也是可选的)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆