如何在" - help"

时间:2017-12-25 23:16:22

标签: python python-3.x command-line-interface python-click

我有这样的代码:

import click

@click.group()
def entry_point():
    pass

entry_point.add_command(lidtk.data.download_documents.main)
entry_point.add_command(lidtk.data.create_ml_dataset.main)
entry_point.add_command(lidtk.classifiers.text_cat.textcat_ngram.cli)

给出了帮助文本:

lidtk --help
Usage: lidtk [OPTIONS] COMMAND [ARGS]...

Options:
  --help  Show this message and exit.

Commands:
  create-dataset  Create sharable dataset from downloaded...
  download        Download 1000 documents of each language.
  textcat

over all 非常接近我想要的。但我想将订单更改为:

Commands:
  download        Download 1000 documents of each language.
  create-dataset  Create sharable dataset from downloaded...
  textcat

如何通过点击来完成?

2 个答案:

答案 0 :(得分:4)

help列出的命令顺序由list_commands()类的click.Group方法设置。因此,实现更改帮助列表顺序的一种方法是继承click.Group并覆盖list_commands以提供所需的订单。

自定义类

此类重写用于装饰命令函数的click.Group.command()方法。它增加了指定help_priority的功能,允许根据需要修改排序顺序:

class SpecialHelpOrder(click.Group):

    def __init__(self, *args, **kwargs):
        self.help_priorities = {}
        super(SpecialHelpOrder, self).__init__(*args, **kwargs)

    def get_help(self, ctx):
        self.list_commands = self.list_commands_for_help
        return super(SpecialHelpOrder, self).get_help(ctx)

    def list_commands_for_help(self, ctx):
        """reorder the list of commands when listing the help"""
        commands = super(SpecialHelpOrder, self).list_commands(ctx)
        return (c[1] for c in sorted(
            (self.help_priorities.get(command, 1), command)
            for command in commands))

    def command(self, *args, **kwargs):
        """Behaves the same as `click.Group.command()` except capture
        a priority for listing command names in help.
        """
        help_priority = kwargs.pop('help_priority', 1)
        help_priorities = self.help_priorities

        def decorator(f):
            cmd = super(SpecialHelpOrder, self).command(*args, **kwargs)(f)
            help_priorities[cmd.name] = help_priority
            return cmd

        return decorator

使用自定义类

通过将cls参数传递给click.group()装饰器,通过group.command()添加到组中的所有命令都可以传递help_priority。优先级默认为1,首先打印较低的数字。

@click.group(cls=SpecialHelpOrder)
def cli():
    """My Excellent CLI"""

@cli.command(help_priority=5)
def my_command():
    ....

这是如何工作的?

这是有效的,因为click是一个设计良好的OO框架。 @click.group()装饰器通常实例化click.Group对象,但允许使用cls参数覆盖此行为。因此,在我们自己的班级继承click.Group并过度使用所需的方法是一件相对容易的事。

这里的步骤:

  1. 覆盖Group.command(),以便装饰的命令可以传递help_priority。在过度使用的装饰器中,为以后的
  2. 捕获所需的优先级
  3. 覆盖Group.get_help()。在过度使用的方法中,将Group.list_commands替换为list_commands,它将根据需要对命令进行排序。
  4. 测试代码:

    import click
    
    @click.group(cls=SpecialHelpOrder)
    def cli():
        pass
    
    @cli.command()
    def command1():
        '''Command #1'''
    
    @cli.command(help_priority=5)
    def command2():
        '''Command #2'''
    
    @cli.command()
    def command3():
        '''Command #3'''
    
    if __name__ == '__main__':
        cli('--help'.split())
    

    测试结果:

    Usage: test.py [OPTIONS] COMMAND [ARGS]...
    
    Options:
      --help  Show this message and exit.
    
    Commands:
      command1  Command #1
      command3  Command #3
      command2  Command #2
    

答案 1 :(得分:3)

在顶部是一个很好的描述,但我们可以更轻松地实现

import click
import collections


from .aws import aws_group
from .db import db_group
from .front import front_group
from .celery import celery_group
from .i18n import i18n_group
from .deprecated import add_deprecated


class OrderedGroup(click.Group):
    def __init__(self, name=None, commands=None, **attrs):
        super(OrderedGroup, self).__init__(name, commands, **attrs)
        #: the registered subcommands by their exported names.
        self.commands = commands or collections.OrderedDict()

    def list_commands(self, ctx):
        return self.commands


@click.group(cls=OrderedGroup)
def entire_group():
    """Entire Group"""


entire_group.add_command(aws_group)
entire_group.add_command(db_group)
entire_group.add_command(front_group)
entire_group.add_command(celery_group)
entire_group.add_command(i18n_group)
add_deprecated(entire_group)

只需将self.commandsDict更改为OrderedDict。结果,我不推荐使用的命令位于列表的底部。