web-dev-qa-db-ja.com

Python /クリック-コマンド間で共有されるオプションとフラグ

私のCLIユーティリティに3つのコマンドがあるとしましょう:_cmd1_、_cmd2_、_cmd3_

そして、_cmd3_に_cmd1_および_cmd2_と同じオプションとフラグを持たせたい。ある種の継承のように。

_@click.command()
@click.options("--verbose")
def cmd1():
    pass

@click.command()
@click.options("--directory")
def cmd2():
    pass

@click.command()
@click.inherit(cmd1, cmd2) # HYPOTHETICAL
def cmd3():
    pass
_

したがって、_cmd3_にはフラグ_--verbose_とオプション_--directory_があります。 Clickでこれを行うことは可能ですか?たぶん私はドキュメントの何かを見落としているだけです...

EDIT:click.group()でこれを実行できることはわかっています。ただし、グループのコマンドの前に、すべてのグループのオプションを指定する必要があります。コマンドの後に通常どおりすべてのオプションが必要です。

_cli.py --verbose --directory /tmp cmd3_-> _cli.py cmd3 --verbose --directory /tmp_

13
jirinovo

私は簡単な解決策を見つけました! https://github.com/pallets/click/issues/108 からスニペットを少し編集しました:

import click


_cmd1_options = [
    click.option('--cmd1-opt')
]

_cmd2_options = [
    click.option('--cmd2-opt')
]


def add_options(options):
    def _add_options(func):
        for option in reversed(options):
            func = option(func)
        return func
    return _add_options


@click.group()
def group(**kwargs):
    pass


@group.command()
@add_options(_cmd1_options)
def cmd1(**kwargs):
    print(kwargs)


@group.command()
@add_options(_cmd2_options)
def cmd2(**kwargs):
    print(kwargs)


@group.command()
@add_options(_cmd1_options)
@add_options(_cmd2_options)
@click.option("--cmd3-opt")
def cmd3(**kwargs):
    print(kwargs)


if __name__ == '__main__':
    group()
11
jirinovo

共通のパラメーターを使用してクラスを定義する

class StdCommand(click.core.Command):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.params.insert(0, click.core.Option(('--default-option',), help='Every command should have one'))

次に、コマンド関数を定義するときにクラスをデコレータに渡します

@click.command(cls=StdCommand)
@click.option('--other')
def main(default_option, other):
  ...
3
user10817547

このコードは、引数からすべてのオプションを抽出します

def extract_params(*args):
    from click import Command
    if len(args) == 0:
        return ['']
    if any([ not isinstance(a, Command) for a in args ]):
        raise TypeError('Handles only Command instances')

    params = [ p.opts() for cmd_inst in args for p in cmd_inst.params ]
    return list(set(params))

今、あなたはそれを使うことができます:

@click.command()
@click.option(extract_params(cmd1, cmd2))
def cmd3():
    pass

このコードはパラメーターのみを抽出し、デフォルト値は抽出しません。必要に応じて改善できます。

0
galra