108

開発した大きなクリック アプリケーションが 1 つありますが、さまざまなコマンド/サブコマンドをナビゲートするのが面倒です。コマンドを個別のファイルにまとめるにはどうすればよいですか? コマンドとそのサブコマンドを別々のクラスに編成することは可能ですか?

これをどのように分離したいかの例を次に示します。

初期化

import click

@click.group()
@click.version_option()
def cli():
    pass #Entry Point

command_cloudflare.py

@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_uptimerobot.py

@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
4

7 に答える 7

47

プロジェクトに次の構造があるとします。

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

この情報はドキュメントではあまり明示的ではありませんが、非常によくコメントされているソース コードを見ると、グループがどのようにネストされているかがわかります。

于 2016-09-09T17:10:11.717 に答える
11

現時点では、このようなものを探しています。各ファイルにグループがあるため、この問題は簡単です。ドキュメントで説明されているように、この問題を解決できます。

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 およびその他のリンターに完全に準拠していることです。

于 2016-03-15T22:47:49.940 に答える
7

これを理解するのにしばらく時間がかかりましたが、これをここに置いて、もう一度やり方を忘れたときに自分に思い出させると思いました例のページ

最初に、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()

次に、いくつかのツール コマンドを 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()

次に、いくつかのコンパイル コマンドを 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()

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

「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

また、cli_tools.py または cli_compile.py を直接実行できることに気付くでしょう。また、そこに main ステートメントを含めました。

于 2020-04-21T21:05:12.677 に答える
0

私はクリックの専門家ではありませんが、ファイルをメインのファイルにインポートするだけで機能するはずです。すべてのコマンドを別々のファイルに移動し、1 つのメイン ファイルに他のコマンドをインポートします。そうすれば、重要な場合に備えて、正確な順序を簡単に制御できます。したがって、メインファイルは次のようになります。

import commands_main
import commands_cloudflare
import commands_uptimerobot
于 2016-03-09T16:18:39.880 に答える