Bra*_*d T 57 python command-line-interface python-click
我有一个我开发的大型点击应用程序,但导航不同的命令/子命令变得越来越粗糙.如何将命令组织到单独的文件中?是否可以将命令及其子命令组织到单独的类中?
这是我想如何分开它的一个例子:
import click
@click.group()
@click.version_option()
def cli():
pass #Entry Point
Run Code Online (Sandbox Code Playgroud)
@cli.group()
@click.pass_context
def cloudflare(ctx):
pass
@cloudflare.group('zone')
def cloudflare_zone():
pass
@cloudflare_zone.command('add')
@click.option('--jumpstart', '-j', default=True)
@click.option('--organization', '-o', default='')
@click.argument('url')
@click.pass_obj
@__cf_error_handler
def cloudflare_zone_add(ctx, url, jumpstart, organization):
pass
@cloudflare.group('record')
def cloudflare_record():
pass
@cloudflare_record.command('add')
@click.option('--ttl', '-t')
@click.argument('domain')
@click.argument('name')
@click.argument('type')
@click.argument('content')
@click.pass_obj
@__cf_error_handler
def cloudflare_record_add(ctx, domain, name, type, content, ttl):
pass
@cloudflare_record.command('edit')
@click.option('--ttl', '-t')
@click.argument('domain')
@click.argument('name')
@click.argument('type')
@click.argument('content')
@click.pass_obj
@__cf_error_handler
def cloudflare_record_edit(ctx, domain):
pass
Run Code Online (Sandbox Code Playgroud)
@cli.group()
@click.pass_context
def uptimerobot(ctx):
pass
@uptimerobot.command('add')
@click.option('--alert', '-a', default=True)
@click.argument('name')
@click.argument('url')
@click.pass_obj
def uptimerobot_add(ctx, name, url, alert):
pass
@uptimerobot.command('delete')
@click.argument('names', nargs=-1, required=True)
@click.pass_obj
def uptimerobot_delete(ctx, names):
pass
Run Code Online (Sandbox Code Playgroud)
jdn*_*dno 67
使用CommandCollection
此方法的缺点是它合并您的命令并仅适用于命令组.imho更好的替代方案是add_command
用来实现相同的结果.
我有一个包含以下树的项目:
cli/
??? __init__.py
??? cli.py
??? group1
? ??? __init__.py
? ??? commands.py
??? group2
??? __init__.py
??? commands.py
Run Code Online (Sandbox Code Playgroud)
每个子命令都有自己的模块,这使得使用更多辅助类和文件管理复杂的实现变得非常容易.在每个模块中,该commands.py
文件包含@click
注释.示例group2/commands.py
:
import click
@click.command()
def version():
"""Display the current version."""
click.echo(_read_version())
Run Code Online (Sandbox Code Playgroud)
如有必要,您可以在模块中轻松创建更多类,并import
在此处使用它们,从而为您的CLI提供Python类和模块的全部功能.
我cli.py
是整个CLI的入口点:
import click
from .group1 import commands as group1
from .group2 import commands as group2
@click.group()
def entry_point():
pass
entry_point.add_command(group1.command_group)
entry_point.add_command(group2.version)
Run Code Online (Sandbox Code Playgroud)
通过此设置,可以非常轻松地按关注点分隔命令,还可以围绕它们构建可能需要的其他功能.到目前为止,它对我很有帮助......
参考:http: //click.pocoo.org/6/quickstart/#nesting-commands
Die*_*tro 23
假设您的项目具有以下结构:
project/
??? __init__.py
??? init.py
??? commands
??? __init__.py
??? cloudflare.py
Run Code Online (Sandbox Code Playgroud)
组只不过是可以嵌套的多个命令和组.您可以将组分成模块并将其导入到您的init.py
文件中,然后cli
使用add_command 将它们添加到组中.
这是一个init.py
例子:
import click
from .commands.cloudflare import cloudflare
@click.group()
def cli():
pass
cli.add_command(cloudflare)
Run Code Online (Sandbox Code Playgroud)
您必须导入位于cloudflare.py文件中的cloudflare组.你commands/cloudflare.py
会看起来像这样:
import click
@click.group()
def cloudflare():
pass
@cloudflare.command()
def zone():
click.echo('This is the zone subcommand of the cloudflare command')
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样运行cloudflare命令:
$ python init.py cloudflare zone
Run Code Online (Sandbox Code Playgroud)
这些信息在文档中并不十分明确,但是如果你看一下评论得很好的源代码,就可以看到如何嵌套组.
我正在寻找这样的东西,在你的情况下很简单,因为你在每个文件中都有组,你可以解决这个问题,如文档中所述:
在init.py
文件中:
import click
from command_cloudflare import cloudflare
from command_uptimerobot import uptimerobot
cli = click.CommandCollection(sources=[cloudflare, uptimerobot])
if __name__ == '__main__':
cli()
Run Code Online (Sandbox Code Playgroud)
这个解决方案的最好的部分是完全符合pep8和其他短路,因为你不需要导入你不会使用的东西,你不需要从任何地方导入*.
我希望这对你的cli有所帮助和好看.
小智 6
我花了一段时间才弄清楚这一点,但我想我会把它放在这里是为了提醒自己,当我再次忘记该怎么做时,我认为问题的一部分是在 click 的 github 页面上提到了 add_command 函数,但不是主要的示例页面
首先让我们创建一个名为 root.py 的初始 python 文件
import click
from cli_compile import cli_compile
from cli_tools import cli_tools
@click.group()
def main():
"""Demo"""
if __name__ == '__main__':
main.add_command(cli_tools)
main.add_command(cli_compile)
main()
Run Code Online (Sandbox Code Playgroud)
接下来让我们将一些工具命令放在一个名为 cli_tools.py 的文件中
import click
# Command Group
@click.group(name='tools')
def cli_tools():
"""Tool related commands"""
pass
@cli_tools.command(name='install', help='test install')
@click.option('--test1', default='1', help='test option')
def install_cmd(test1):
click.echo('Hello world')
@cli_tools.command(name='search', help='test search')
@click.option('--test1', default='1', help='test option')
def search_cmd(test1):
click.echo('Hello world')
if __name__ == '__main__':
cli_tools()
Run Code Online (Sandbox Code Playgroud)
接下来让我们将一些编译命令放在一个名为 cli_compile.py 的文件中
import click
@click.group(name='compile')
def cli_compile():
"""Commands related to compiling"""
pass
@cli_compile.command(name='install2', help='test install')
def install2_cmd():
click.echo('Hello world')
@cli_compile.command(name='search2', help='test search')
def search2_cmd():
click.echo('Hello world')
if __name__ == '__main__':
cli_compile()
Run Code Online (Sandbox Code Playgroud)
运行 root.py 现在应该给我们
Usage: root.py [OPTIONS] COMMAND [ARGS]...
Demo
Options:
--help Show this message and exit.
Commands:
compile Commands related to compiling
tools Tool related commands
Run Code Online (Sandbox Code Playgroud)
运行“root.py compile”应该给我们
Usage: root.py compile [OPTIONS] COMMAND [ARGS]...
Commands related to compiling
Options:
--help Show this message and exit.
Commands:
install2 test install
search2 test search
Run Code Online (Sandbox Code Playgroud)
您还会注意到您可以直接运行 cli_tools.py 或 cli_compile.py 并且我在其中包含了一个主要语句
归档时间: |
|
查看次数: |
24661 次 |
最近记录: |