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

  • 本文关键字:默认 参数 Argparse python argparse
  • 更新时间 :
  • 英文 :


我有一个特定的脚本,它通常用2个位置参数和一堆可选参数来调用。

script.py <file1> <file2> 

我想添加另一个子分析器,当我传递可选参数时应该调用它。

script.py -file_list <files.list>

基本上,我需要的是,当传递-file_list时,解析器不应该查找file1file2。我不希望默认情况需要另一个选项来调用它(因为默认情况已经在使用中,因此我不想破坏它(。

我试着保持默认解析器的原样,并为-file_list创建子解析器。但是解析器仍然期望位置参数file1file2

示例代码(这不能像我希望的那样工作(:

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()

也许我需要为默认情况创建一个单独的子分析器;但所有子解析器似乎都需要一个额外的命令来调用它们。我希望当-file_list未通过时自动调用默认情况

您在传递其他选项时提到,所以我认为保留argparse有很好的动机。假设没有其他职位,你可以试试:

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='*');

这接受"--filelist",而不需要位置文件(结果是空列表(:

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

其他文件-但将该列表限制为2需要您自己在解析后进行测试:

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

但它也接受这两种形式。同样,你自己的解析后代码将不得不整理出冲突的消息:

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

你必须处理两者都不提供的情况:

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

帮助:

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

因此,我所创建的内容接受这两种形式的输入,但不限制它们。

我尝试使用mutually_exclusive_group,但它只适用于nargs='?'。我曾经认为nargs='*'在一个小组中工作,但要么我的记忆有问题,要么有一个补丁改变了事情。m-x组中的位置必须具有"required=False"值。

CCD_ 10实际上是一种特殊的CCD_。因此,如果您使用"prog file1 file2{cmd1,cmd2}"创建解析器,则在检查第三个字符串之前,它仍然需要这两个文件名。包括subparsers在内的所有positionals都是按位置处理的,而不是按值处理的。标记的参数(optional(可以按任何顺序出现,但不会覆盖positionals

如果您首先定义subparsers,那么第一个位置必须是其中一个命令。subparsers不是必需的(默认情况下(,但这不会改变对其他位置的处理。

工作互斥组

如果我们还指定了一个default,那么nargs='*'确实有效。这是一个未记录的细节。我把它忘了,直到我看了代码(特别是_get_positional_kwargs方法(。*被标记为required,除非它被赋予default。前段时间在一个或多个bug/问题中已经讨论过了。

因此可以使位置列表和"--file_list"互斥

In [71]: parser = argparse.ArgumentParser()
In [72]: parser.add_argument('--other'); # other optionals
In [73]: group = parser.add_mutually_exclusive_group(required=True)
In [74]: group.add_argument('--file_list');
In [75]: group.add_argument('files', nargs='*', default=[]);

良好案例:

In [76]: parser.parse_args('--other foobar file1 file2'.split())
Out[76]: Namespace(other='foobar', file_list=None, files=['file1', 'file2'])
In [77]: parser.parse_args('--other foobar --file_list file3'.split())
Out[77]: Namespace(other='foobar', file_list='file3', files=[])

如果两者都使用:

In [78]: parser.parse_args('--other foobar --file_list file3 file1 file2'.split())
usage: ipykernel_launcher.py [-h] [--other OTHER] [--file_list FILE_LIST]
[files ...]
ipykernel_launcher.py: error: argument files: not allowed with argument --file_list

如果两者都不提供:

In [79]: parser.parse_args('--other foobar'.split())
usage: ipykernel_launcher.py [-h] [--other OTHER] [--file_list FILE_LIST]
[files ...]
ipykernel_launcher.py: error: one of the arguments --file_list files is required

现在的用法看起来像:

In [81]: parser.print_usage()
usage: ipykernel_launcher.py [-h] [--other OTHER] [--file_list FILE_LIST]
[files ...]

它仍然无法控制文件的数量——除非必须至少有一个。

相关内容

  • 没有找到相关文章

最新更新