如何将具有一组子命令的Click命令拆分为多个文件?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将具有一组子命令的Click命令拆分为多个文件?相关的知识,希望对你有一定的参考价值。
我有一个我开发的大型点击应用程序,但导航不同的命令/子命令变得越来越粗糙。如何将命令组织到单独的文件中?是否可以将命令及其子命令组织到单独的类中?
这是我想如何分开它的一个例子:
在里面
import click
@click.group()
@click.version_option()
def cli():
pass #Entry Point
command_cloud flare.朋友
@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
command_uptime robot.朋友
@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
使用CommandCollection
的缺点是它合并了您的命令并且只能与命令组一起使用。更好的替代方案是使用add_command
来实现相同的结果。
我有一个包含以下树的项目:
cli/
├── __init__.py
├── cli.py
├── group1
│ ├── __init__.py
│ ├── commands.py
└── group2
├── __init__.py
└── commands.py
每个子命令都有自己的模块,这使得使用更多辅助类和文件管理复杂的实现变得非常容易。在每个模块中,commands.py
文件包含@click
注释。示例group2/commands.py
:
import click
@click.command()
def version():
"""Display the current version."""
click.echo(_read_version())
如有必要,您可以在模块中轻松创建更多类,并在此处使用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)
通过此设置,可以非常轻松地按关注点分隔命令,还可以围绕它们构建可能需要的其他功能。到目前为止,它对我很有帮助......
参考:http://click.pocoo.org/6/quickstart/#nesting-commands
假设您的项目具有以下结构:
project/
├── __init__.py
├── init.py
└── commands
├── __init__.py
└── cloudflare.py
组只是多个命令,组可以嵌套。您可以将组分成模块并将其导入init.py
文件,并使用add_command将它们添加到cli
组。
这是一个init.py
的例子:
import click
from .commands.cloudflare import cloudflare
@click.group()
def cli():
pass
cli.add_command(cloudflare)
您必须导入位于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')
然后你可以像这样运行cloudflare命令:
$ python init.py cloudflare zone
这些信息在文档中并不十分明确,但是如果你看一下评论得很好的源代码,就可以看到如何嵌套组。
我正在寻找这样的东西,在你的情况下很简单,因为你在每个文件中都有组,你可以解决这个问题,如documentation中所解释的:
在init.py
文件中:
import click
from command_cloudflare import cloudflare
from command_uptimerobot import uptimerobot
cli = click.CommandCollection(sources=[cloudflare, uptimerobot])
if __name__ == '__main__':
cli()
该解决方案的最佳部分是完全符合pep8和其他短接线,因为您不需要导入您不会使用的东西,也不需要从任何地方导入*。
我不是点击专家,但只需将文件导入主文件即可。我会将所有命令移到单独的文件中,并让一个主文件导入其他文件。这样就可以更容易地控制确切的顺序,以防它对您来说很重要。所以你的主文件看起来像:
import commands_main
import commands_cloudflare
import commands_uptimerobot
以上是关于如何将具有一组子命令的Click命令拆分为多个文件?的主要内容,如果未能解决你的问题,请参考以下文章