简体   繁体   English

Argparse:当给出某个可选参数时,如何从默认解析器切换到不同的子解析器?

[英]Argparse: How to switch from default parser to a different subparser when a certain optional argument is given?

I have a certain script that is normally called with 2 positional arguments and bunch of optional arguments.我有一个通常用 2 个位置 arguments 和一堆可选 arguments 调用的脚本。

script.py <file1> <file2> 

I want to add another subparser which should be called when I pass an optional argument.我想添加另一个子解析器,当我传递一个可选参数时应该调用它。

script.py -file_list <files.list>

Basically, what I require is that when -file_list is passed, the parser shouldn't look for file1 and file2 .基本上,我需要的是当-file_list被传递时,解析器不应该寻找file1file2 I do not want the default case to require another option to invoke it (since the default case is already in use and thus I do not want to break it).我不希望默认情况需要另一个选项来调用它(因为默认情况已经在使用中,因此我不想破坏它)。

I tried keeping the default parser as is and creating subparser for -file_list .我尝试保持默认解析器不变并为-file_list创建子解析器。 But the parser still expects the positional arguments file1 and file2 .但是解析器仍然需要位置 arguments file1file2

Sample code (this doesn't work as I want it to):示例代码(这不像我想要的那样工作):

args = argparse.ArgumentParser()

#default arguments
args.add_argument("file1", type=str)
args.add_argument("file2", type=str)

#subparser for file_list
file_list_sp = args.add_subparsers()
file_list_parser = file_list_sp.ad_parser("-file_list")
file_list_parser.add_argument("file_list")

all_args = args.parse_args()

Maybe I need to create a seperate subparser for the default case;也许我需要为默认情况创建一个单独的子解析器; but all subparsers seem to need an extra command to invoke them.但所有子解析器似乎都需要一个额外的命令来调用它们。 I want default case to be invoked automatically whenever -file_list is not passed我希望在未传递 -file_list 时自动调用默认情况

You mention in passing other optionals, so I assume there's good incentive to keep argparse .您在传递其他选项时提到了,所以我认为保留argparse有很好的动机。 Assuming there aren't other positionals, you could try:假设没有其他位置,您可以尝试:

In [23]: parser = argparse.ArgumentParser()    
In [24]: parser.add_argument('--other'); # other optionals
In [25]: parser.add_argument('--filelist');   
In [26]: parser.add_argument('files', nargs='*');

This accepts the '--filelist', without requiring the positional files, (with a resulting empty list):这接受“--filelist”,而不需要位置文件,(结果为空列表):

In [27]: parser.parse_args('--filelist alist'.split())
Out[27]: Namespace(other=None, filelist='alist', files=[])

Other the files - but restricting that list to 2 requires your own testing after parsing:其他文件 - 但将该列表限制为 2 需要您在解析后进行自己的测试:

In [28]: parser.parse_args('file1 file2'.split())
Out[28]: Namespace(other=None, filelist=None, files=['file1', 'file2'])

But it also accepts both forms.但它也接受 forms。 Again your own post parsing code will have to sort out the conflicting message:同样,您自己的后解析代码将不得不整理出冲突的消息:

In [29]: parser.parse_args('file1 file2 --filelist xxx'.split())
Out[29]: Namespace(other=None, filelist='xxx', files=['file1', 'file2'])

And you have to deal with the case where neither is provided:你必须处理两者都没有提供的情况:

In [30]: parser.parse_args('--other foobar'.split())
Out[30]: Namespace(other='foobar', filelist=None, files=[])

The help:帮助:

In [32]: parser.print_help()
usage: ipykernel_launcher.py [-h] [--other OTHER] [--filelist FILELIST]
                             [files ...]

positional arguments:
  files

optional arguments:
  -h, --help           show this help message and exit
  --other OTHER
  --filelist FILELIST

So what I've created accepts both forms of input, but does not constrain them.因此,我创建的内容同时接受 forms 输入,但不限制它们。

I tried using a mutually_exclusive_group, but that only works with nargs='?'我尝试使用互斥组,但这仅适用于nargs='?' . . I thought at one time nargs='*' worked in a group, but either my memory is wrong, or there was a patch that changed things.我曾经以为nargs='*'在一个小组中工作,但要么我的 memory 是错误的,要么有一个补丁改变了事情。 A positional in a mx-group has to have 'required=False' value. mx-group 中的位置必须具有 'required=False' 值。

A subparsers is actually a special kind of positional . subparsers实际上是一种特殊的positional So if you created parser with usage 'prog file1 file2 {cmd1, cmd2}' it would still expect the 2 file names before checking on the third string.因此,如果您使用 'prog file1 file2 {cmd1, cmd2}' 创建了解析器,它仍然会在检查第三个字符串之前需要 2 个文件名。 All positionals , including subparsers are handled by position, not value.所有positionals ,包括子解析器都由subparsers处理,而不是值。 A flagged argument ( optional ) can occur in any order, but does not override the positionals .标记的参数( optional )可以以任何顺序出现,但不会覆盖positionals

And if you define the subparsers first, then the first positional has to be one of those commands.如果您首先定义subparsers ,那么第一个位置必须是这些命令之一。 subparsers are not required (by default), but that doesn't change the handling of other positionals. subparsers (默认情况下),但这不会改变其他位置的处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM