如何在“点击链接”组中对命令列表显示进行分类? 自定义类使用自定义类这是如何工作的?测试代码结果

我正在启动一个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组内不允许使用子组。

yg1438 回答:如何在“点击链接”组中对命令列表显示进行分类? 自定义类使用自定义类这是如何工作的?测试代码结果

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

自定义类

class GroupedGroup(click.Group):

    def command(self,*args,**kwargs):
        """Gather the command help groups"""
        help_group = kwargs.pop('group',None)
        decorator = super(GroupedGroup,self).command(*args,**kwargs)

        def wrapper(f):
            cmd = decorator(f)
            cmd.help_group = help_group
            return cmd

        return wrapper

    def format_commands(self,ctx,formatter):
        # Modified fom the base class method

        commands = []
        for subcommand in self.list_commands(ctx):
            cmd = self.get_command(ctx,subcommand)
            if not (cmd is None or cmd.hidden):
                commands.append((subcommand,cmd))

        if commands:
            longest = max(len(cmd[0]) for cmd in commands)
            # allow for 3 times the default spacing
            limit = formatter.width - 6 - longest

            groups = {}
            for subcommand,cmd in commands:
                help_str = cmd.get_short_help_str(limit)
                subcommand += ' ' * (longest - len(subcommand))
                groups.setdefault(
                    cmd.help_group,[]).append((subcommand,help_str))

            with formatter.section('Commands'):
                for group_name,rows in groups.items():
                    with formatter.section(group_name):
                        formatter.write_dl(rows)

使用自定义类

要使用自定义类,请使用cls参数将类传递给click.group()装饰器。

@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()装饰器通常会实例化click.Group对象,但允许使用cls参数覆盖此行为。因此,从我们自己的类中的click.Group继承并覆盖所需的方法是相对容易的事情。

在这种情况下,我们重写click.Group.command()装饰器以为每个命令收集所需的帮助组。然后,在构建帮助时,我们将覆盖click.Group.format_commands()方法以使用这些组。

测试代码

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
本文链接:https://www.f2er.com/3146130.html

大家都在问