Python 如何在单击链接组中对命令列表显示进行分类?

Python 如何在单击链接组中对命令列表显示进行分类?,python,command-line-interface,python-click,Python,Command Line Interface,Python Click,我正在启动一个CLI管道类型的应用程序项目,该项目最终将有一个相当大的命令集合(可以通过插件进一步扩展)。因此,我想在--help文本中对它们进行分类: 下面是它现在的样子: Usage: my_pipe [OPTIONS] COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]... Options: --help Show this message and exit. Commands: another_filter help ab

我正在启动一个CLI管道类型的应用程序项目,该项目最终将有一个相当大的命令集合(可以通过插件进一步扩展)。因此,我想在
--help
文本中对它们进行分类:

下面是它现在的样子:

Usage: my_pipe [OPTIONS] COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]...

Options:
  --help         Show this message and exit.

Commands:
  another_filter     help about that filter
  another_generator  help about that generator
  another_sink       help about that sink
  some_filter        help about this filter
  some_generator     help about this generator
  some_sink          help about this sink
这或多或少是我希望它看起来的样子:

Usage: my_pipe [OPTIONS] COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]...

Options:
  --help         Show this message and exit.

Commands:

  Generators:
     some_generator     help about this generator
     another_generator  help about that generator

  Filters:
     some_filter        help about this filter
     another_filter     help about that filter

  Sinks:
     some_sink          help about this sink
     another_sink       help about that sink

如何做到这一点?请注意,除了
--help
的外观之外,我对扁平的逻辑命令组织感到满意。此外,子组不是一个选项,因为它们不允许在
chain=True
组中使用。

如果从
click.group继承,则可以添加一些代码对命令进行分组,然后在帮助中显示这些组

自定义类 使用自定义类 要使用自定义类,请使用
cls
参数将该类传递给
click.group()
decorator

@click.group(cls=GroupedGroup)
def cli():
    """My awesome cli"""
然后,为每个命令标记要包含在其中的命令的帮助组,如:

@cli.command(group='A Help Group')
def command():
    """This is a command"""
这是怎么回事? 这是因为click是一个设计良好的OO框架。
@click.group()
decorator通常实例化
click.group
对象,但允许使用
cls
参数覆盖此行为。因此,在我们自己的类中继承
click.Group
并重写所需的方法是一件相对容易的事情

在本例中,我们重写
click.Group.command()
decorator,为每个命令收集所需的帮助组。然后重写
click.Group.format\u commands()
方法,以便在构建帮助时使用这些组

测试代码 结果
试试docopt:它基本上可以让您在模块的docstring中编写帮助文本,就像您已经拥有的一样,并为您创建一个参数解析器。@magarnicle:我们的计划是在插件中添加新命令,所以我认为docopt在这种情况下不是一个好方法。除非是这样?在这种情况下,我很高兴听到这个消息。这可能不是不可能的,但我的第一个猜测是插件必须修改docstring或docopt所做的任何事情。两者似乎都违背了docopt的目的,即不必使用代码解析args。出色的writeup!这工作得很好,正是我一直在寻找的。
@cli.command(group='A Help Group')
def command():
    """This is a command"""
import click

@click.group(cls=GroupedGroup)
def cli():
    """My awesome cli"""

@cli.command(group='Generators')
def some_generator():
    """This is Some Generator"""

@cli.command(group='Generators')
def another_generator():
    """This is Another Generator"""

@cli.command(group='Filters')
def some_filter():
    """This is Some Filter"""

@cli.command(group='Filters')
def another_filter():
    """This is Another Filter"""

cli()
Usage: test.py [OPTIONS] COMMAND [ARGS]...

  My awesome cli

Options:
  --help  Show this message and exit.

Commands:

  Filters:
    another-filter     This is Another Filter
    some-filter        This is Some Filter

  Generators:
    another-generator  This is Another Generator
    some-generator     This is Some Generator