带有 argument_groups 和 mututally_exclusive_group 的 argparse
argparse with argument_groups and mututally_exclusive_group
我有以下内容:
def parser():
p = argparse.ArgumentParser()
people = p.add_argument_group('people_list')
meg = people.add_mutually_exclusive_group()
meg.add_argument('--config-file')
g = meg.add_argument_group('people')
g.add_argument('--name')
g.add_argument('--age')
return p
p = parser()
p.parse_args(['--config-file', 'cfg_file', '--name', 'Bob', '--age', '3'])
我预计这会因 mutually_exclusive
组而引起投诉。请注意,这是实际代码的一个片段,我有几个 argument_groups
需要使用,但是在这个 argument_group('people_list')
中,我希望用户指定一个配置文件,或者任何其他参数。
所以,我的用户应该可以说
prog --config-file cfg_file
或
prog --name Bob --age 3
但不是
prog --config-file cfg_file --name Bob --age 3
我做错了什么?
这是帮助:
usage: foo [-h] [--config-file CONFIG_FILE] [--name NAME]
[--age AGE]
optional arguments:
-h, --help show this help message and exit
people_list:
--config-file CONFIG_FILE
像 people
这样的参数组控制帮助行的显示方式。因此标题为 people_list
.
的部分
互斥组控制用法的格式,并检查参数的共现。从技术上讲它是参数组的一个子类,但是这两种组没有太多交互。
您可以在参数组中嵌套互斥组,就像您在此处所做的那样。但是您不能将一个参数组嵌套在另一个组(任何一种)中。或者更确切地说,它会接受这样的定义,但它没有做任何特别的事情。所以 name
和 age
已经被添加到解析器中(如使用中所见),但没有添加到 meg
或 people
中。而如果将互斥组添加到另一个 MXGroup,效果就是创建一个大的平面组。
所以,除了一个小例外,不要试图将一个组嵌套在另一个组中。他们的定义不够通用,无法以这种方式做任何有用的事情。
如果您将 name
和 age
添加到 meg
,那么帮助将是:
usage: foo [-h]
[--config-file CONFIG_FILE | --name NAME | --age AGE]
optional arguments:
-h, --help show this help message and exit
people_list:
--config-file CONFIG_FILE
--name NAME
--age AGE
这将 object 与 name
或 age
一起使用 config-file
。但它也会 object 同时使用 name
和 age
。
有bug-issue要求广义嵌套mutually-xxx-groups。一旦实现,它就可以处理这种通用逻辑。但就目前而言,还不能。假设您可以设置所需的测试,那么理想的用法线应该是什么样的?设置测试相对容易,但要产生有意义的使用则要困难得多。
现在我建议您自己编写 usage
。使用 argument groups
对参数帮助行进行分组。解析后做自己的交互测试。您可以使用 p.error...
来生成错误消息。如果您明智地选择默认值,则不难测试参数,例如
if args.config_file is not None and
(args.name is not None or args.age is not None):
p.error('...')
我有以下内容:
def parser():
p = argparse.ArgumentParser()
people = p.add_argument_group('people_list')
meg = people.add_mutually_exclusive_group()
meg.add_argument('--config-file')
g = meg.add_argument_group('people')
g.add_argument('--name')
g.add_argument('--age')
return p
p = parser()
p.parse_args(['--config-file', 'cfg_file', '--name', 'Bob', '--age', '3'])
我预计这会因 mutually_exclusive
组而引起投诉。请注意,这是实际代码的一个片段,我有几个 argument_groups
需要使用,但是在这个 argument_group('people_list')
中,我希望用户指定一个配置文件,或者任何其他参数。
所以,我的用户应该可以说
prog --config-file cfg_file
或
prog --name Bob --age 3
但不是
prog --config-file cfg_file --name Bob --age 3
我做错了什么?
这是帮助:
usage: foo [-h] [--config-file CONFIG_FILE] [--name NAME]
[--age AGE]
optional arguments:
-h, --help show this help message and exit
people_list:
--config-file CONFIG_FILE
像 people
这样的参数组控制帮助行的显示方式。因此标题为 people_list
.
互斥组控制用法的格式,并检查参数的共现。从技术上讲它是参数组的一个子类,但是这两种组没有太多交互。
您可以在参数组中嵌套互斥组,就像您在此处所做的那样。但是您不能将一个参数组嵌套在另一个组(任何一种)中。或者更确切地说,它会接受这样的定义,但它没有做任何特别的事情。所以 name
和 age
已经被添加到解析器中(如使用中所见),但没有添加到 meg
或 people
中。而如果将互斥组添加到另一个 MXGroup,效果就是创建一个大的平面组。
所以,除了一个小例外,不要试图将一个组嵌套在另一个组中。他们的定义不够通用,无法以这种方式做任何有用的事情。
如果您将 name
和 age
添加到 meg
,那么帮助将是:
usage: foo [-h]
[--config-file CONFIG_FILE | --name NAME | --age AGE]
optional arguments:
-h, --help show this help message and exit
people_list:
--config-file CONFIG_FILE
--name NAME
--age AGE
这将 object 与 name
或 age
一起使用 config-file
。但它也会 object 同时使用 name
和 age
。
有bug-issue要求广义嵌套mutually-xxx-groups。一旦实现,它就可以处理这种通用逻辑。但就目前而言,还不能。假设您可以设置所需的测试,那么理想的用法线应该是什么样的?设置测试相对容易,但要产生有意义的使用则要困难得多。
现在我建议您自己编写 usage
。使用 argument groups
对参数帮助行进行分组。解析后做自己的交互测试。您可以使用 p.error...
来生成错误消息。如果您明智地选择默认值,则不难测试参数,例如
if args.config_file is not None and
(args.name is not None or args.age is not None):
p.error('...')