如何在argparse中显示所有子解析器的帮助信息?

6 投票
1 回答
7538 浏览
提问于 2025-04-17 16:09

我写了一个Python脚本,这个脚本做了很多事情,所以有很多选项。为了更好地管理这些选项,我把它们分成了几个子解析器,同时也使用了父解析器来把一些共同的选项归在一起。

我想要一个帮助选项,这样可以显示所有命令及其选项的帮助信息。请问有没有办法做到这一点,而不需要重写format_help这个方法呢?

我看到过一个类似的问题,但对我来说,选项的分组并不是特别重要,我只想要看到这些选项。

举个例子:

general_group = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter,add_help=False)
general_group.add_argument('--threads', action='store_true', default=False)
second_group = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter,add_help=False)
second_group.add_argument('--sleep', action='store', default=60, type=int)
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
subparsers=parser.add_subparsers(dest='action')
subparsers.add_parser('Restart',parents=[general_group,second_group])
subparsers.add_parser('Start',parents=[general_group])

args = parser.parse_args()

在这种情况下,我希望如果有人运行 ./script.py -h,他们能在帮助信息中看到线程选项。

1 个回答

10

问题在于,在以下代码行中:

subparsers=parser.add_subparsers(dest='action')
subparsers.add_parser('Restart',parents=[general_group,second_group])
subparsers.add_parser('Start',parents=[general_group])

你把 general_group 作为子解析器的父级添加了进去,这样主解析器就不知道它们的存在了,这导致你在运行 ./script.py -h 时看不到 --threads 这个选项。如果你打算把它作为所有子解析器的父级,那么你应该把它放在最上面的解析器父级:

parser = argparse.ArgumentParser(parents=[general_group])
subparsers=parser.add_subparsers(dest='action')
subparsers.add_parser('Restart',parents=[second_group])
subparsers.add_parser('Start')

这样就会得到:

$ python script.py -h
usage: script.py [-h] [--threads] {Restart,Start} ...

positional arguments:
  {Restart,Start}

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

不过要注意,在这种情况下,这个选项只属于父解析器,而不属于子解析器,这意味着下面的代码:

$python script.py --threads Start

是正确的,而:

$ python script.py Start --threads
usage: script.py [-h] [--threads] {Restart,Start} ...
script.py: error: unrecognized arguments: --threads

则不正确,因为 --threads 并没有被子解析器“继承”。如果你想让 --threads 也出现在子解析器中,你必须在它的 parents 参数中指定它:

parser = argparse.ArgumentParser(parents=[general_group])
subparsers=parser.add_subparsers(dest='action')
subparsers.add_parser('Restart',parents=[general_group, second_group])
subparsers.add_parser('Start', parents=[general_group])

这样应该能实现你想要的效果:

$ python script.py -h
usage: script.py [-h] [--threads] {Restart,Start} ...

positional arguments:
  {Restart,Start}

optional arguments:
  -h, --help       show this help message and exit
  --threads
$ python script.py Start -h
usage: script.py Start [-h] [--threads]

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

撰写回答