我有一个我开发的大型点击应用程序,但导航不同的命令/子命令变得越来越粗糙.如何将命令组织到单独的文件中?是否可以将命令及其子命令组织到单独的类中?
这是我想如何分开它的一个例子:
import click @click.group() @click.version_option() def cli(): pass #Entry Point
@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
@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
jdno.. 67
使用CommandCollection
此方法的缺点是它合并您的命令并仅适用于命令组.imho更好的替代方案是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
使用CommandCollection
此方法的缺点是它合并您的命令并仅适用于命令组.imho更好的替代方案是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
文件中,然后cli
使用add_command 将它们添加到组中.
这是一个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
这些信息在文档中并不十分明确,但是如果你看一下评论得很好的源代码,就可以看到如何嵌套组.
我正在寻找这样的东西,在你的情况下很简单,因为你在每个文件中都有组,你可以解决这个问题,如文档中所述:
在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和其他短路,因为你不需要导入你不会使用的东西,你不需要从任何地方导入*.
我希望这对你的cli有所帮助和好看.