![](/img/trans.png)
[英]How can I split my Click commands, each with a set of sub-commands, into multiple files?
[英]How can I define the order of click sub-commands in "--help"
我有這樣的代碼:
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
這一切都非常接近我想要的。 但我想將順序更改為:
Commands:
download Download 1000 documents of each language.
create-dataset Create sharable dataset from downloaded...
textcat
如何使用單擊來完成此操作?
這是頂部的一個很好的描述,但我們可以更輕松地實現它
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.commands
從Dict
更改為OrderedDict
。 因此,我已棄用的命令位於列表底部。
help列出的命令順序由click.Group
類的list_commands()
方法設置。 因此,一種滿足更改幫助列表順序要求的方法是繼承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
繼承並覆蓋所需的方法是相對容易的事情。
步驟如下:
Group.command()
以便可以將裝飾后的命令傳遞給help_priority
。 在重寫的裝飾器中,捕獲所需的優先級以備后用 Group.get_help()
。 在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
Максим Стукало的回答對我幫助很大。 但是,它缺少一些打字信息。 鑒於我們總是嚴格打字並且我無法編輯帖子,我想我會創建另一個帖子,也許它可以幫助某人:
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.