argparse:当存在子解析器时如何分离未知(和可选)参数。(子解析器也是可选的)

2023-12-23

我有以下代码

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 as argv = ['abc', 'def'] or argv = ['abc']

I get

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

我所期待的是得到['abc', 'def']在未知参数的元组中。 我检查了很多 stackoverflow 答案(例如ans 1 https://stackoverflow.com/questions/20746494/argparse-optional-positional-argument-and-subparsers-arguments, ans 2 https://stackoverflow.com/questions/37049428/how-do-i-make-an-argparse-argument-optional-when-using-subparsers, ans 3 https://stackoverflow.com/questions/4480075/argparse-optional-positional-arguments?rq=1, ans 4 https://stackoverflow.com/questions/8521612/argparse-optional-subparser-for-version)和错误报告(例如br 1 https://bugs.python.org/issue9253) and a lot但我似乎找不到办法做到这一点。这是一个未解决的错误吗?我期望这可以完成是错误的吗?如果无法做到这一点,是否有任何解决方法?

另外需要澄清的是,['abc', 'def']从元组获取的数据必须传递给其他函数进行处理。

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


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

用简单的位置来说明:

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选择:

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,它会引发错误。

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

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

改变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'])
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

argparse:当存在子解析器时如何分离未知(和可选)参数。(子解析器也是可选的) 的相关文章

随机推荐