argparse mutually exclusive group title and descri

2020-06-23 01:44发布

问题:

Why I can't I have an argparse mutually exclusive group with a title or description, so that it appears as a separate category under the --help message?

I have an options group with a name and a description:

import argparse

parser = argparse.ArgumentParser()

group = parser.add_argument_group(
    'foo options', 'various (mutually exclusive) ways to do foo')
group.add_argument('--option_a', action='store_true', help='option a')
group.add_argument('--option_b', action='store_true', help='option b')

args = parser.parse_args()

Output of --help:

usage: foo.py [-h] [--option_a] [--option_b]

optional arguments:
  -h, --help  show this help message and exit

foo options:
  various (mutually exclusive) ways to do foo

  --option_a  option a
  --option_b  option b

But I want to make the group mutually exclusive:

import argparse

parser = argparse.ArgumentParser()

group = parser.add_mutually_exclusive_group()  # here
group.add_argument('--option_a', action='store_true', help='option a')
group.add_argument('--option_b', action='store_true', help='option b')

args = parser.parse_args()

Output of --help:

usage: foo.py [-h] [--option_a | --option_b]

optional arguments:
  -h, --help  show this help message and exit
  --option_a  option a
  --option_b  option b

There is no distinction in the help message that these options are part of a group, and I can't specify a title/description (add_mutually_exclusive_group takes no additional positional arguments). Does anyone have a workaround?

回答1:

Why? Because that's how it's coded!

Mutually exclusive groups are a subclass of ArgumentGroups, but the interface is different. Purpose is also quite different. An argument group controls the display of the help lines. It does nothing to parsing. A mutually exclusive group checks arguments during parsing, and is used when formatting the usage line. But it has no effect on the help lines.

But it is possible to embed a mutually exclusive group in an argument group (but not the other way around). That should produce what you want.

In [2]: parser = argparse.ArgumentParser()
In [3]: group = parser.add_argument_group(
   ...:  'foo options', 'various (mutually exclusive) ways to do foo')
In [4]: mxg = group.add_mutually_exclusive_group() 
In [5]: mxg.add_argument('--option_a', action='store_true', help='option a');
In [6]: mxg.add_argument('--option_b', action='store_true', help='option b');

In [7]: parser.print_help()
usage: ipython3 [-h] [--option_a | --option_b]

optional arguments:
  -h, --help  show this help message and exit

foo options:
  various (mutually exclusive) ways to do foo

  --option_a  option a
  --option_b  option b

There are more details in the code itself, and in a bug/issue or two, but this should get you going.