[英]How can I define the order of click sub-commands in "--help"
I have code like this:我有这样的代码:
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)
which gives the help text:这给出了帮助文本:
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
which is over all pretty close to what I want.这一切都非常接近我想要的。 But I would like to change the order to:
但我想将顺序更改为:
Commands:
download Download 1000 documents of each language.
create-dataset Create sharable dataset from downloaded...
textcat
How can this be done using click?如何使用单击来完成此操作?
It's a nice description at the top, but we can achieve it more easily这是顶部的一个很好的描述,但我们可以更轻松地实现它
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)
Just change self.commands
from Dict
to OrderedDict
.只需将
self.commands
从Dict
更改为OrderedDict
。 As a result, my deprecated commands at a bottom of list.因此,我已弃用的命令位于列表底部。
The order of the commands listed by help is set by the list_commands()
method of the click.Group
class. help列出的命令顺序由
click.Group
类的list_commands()
方法设置。 So, one way to approach the desire to change the help listing order is to inherit for click.Group
and override list_commands
to give the desired order. 因此,一种满足更改帮助列表顺序要求的方法是继承
click.Group
并覆盖list_commands
以给出所需的顺序。
This class overrides the click.Group.command()
method which is used to decorate command functions. 此类重写用于装饰命令功能的
click.Group.command()
方法。 It adds the ability to specify a help_priority
, which allows the sort order to be modified as desired: 它增加了指定
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
By passing the cls
parameter to the click.group()
decorator, any commands added to the group via the the group.command()
can be passed a help_priority
. 由经过的
cls
参数到click.group()
装饰,任何命令经由所述添加到组group.command()
可以传递一个help_priority
。 The priorities default to 1, and lower numbers are printed first. 优先级默认为1,并且较低的数字首先打印。
@click.group(cls=SpecialHelpOrder)
def cli():
"""My Excellent CLI"""
@cli.command(help_priority=5)
def my_command():
....
This works because click is a well designed OO framework. 之所以可行,是因为click是一个设计良好的OO框架。 The
@click.group()
decorator usually instantiates a click.Group
object but allows this behavior to be over ridden with the cls
parameter. @click.group()
装饰器通常会实例化click.Group
对象,但允许使用cls
参数覆盖此行为。 So it is a relatively easy matter to inherit from click.Group
in our own class and over ride the desired methods. 因此,在我们自己的类中从
click.Group
继承并覆盖所需的方法是相对容易的事情。
Steps here: 步骤如下:
Group.command()
so that decorated commands can be passed a help_priority
. Group.command()
以便可以将装饰后的命令传递给help_priority
。 In the over ridden decorator, capture the desired priority for later Group.get_help()
. Group.get_help()
。 In the over ridden method, substitute Group.list_commands
with a list_commands
which will order the commands as desired. Group.list_commands
方法中,将Group.list_commands
替换为list_commands
,它将按需要对命令进行排序。 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
The answer by Максим Стукало helped me a lot. Максим Стукало的回答对我帮助很大。 However, it was missing some typing info.
但是,它缺少一些打字信息。 Given, we always do strict typing and given I can't edit the post, I figured I'd create another post, maybe it helps someone:
鉴于我们总是严格打字并且我无法编辑帖子,我想我会创建另一个帖子,也许它可以帮助某人:
import collections
from typing import Optional, Mapping
import click
class OrderedGroup(click.Group):
def __init__(self, name: Optional[str] = None, commands: Optional[Mapping[str, click.Command]] = None, **kwargs):
super(OrderedGroup, self).__init__(name, commands, **kwargs)
#: the registered subcommands by their exported names.
self.commands = commands or collections.OrderedDict()
def list_commands(self, ctx: click.Context) -> Mapping[str, click.Command]:
return self.commands
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.