如何在选项装饰器中访问单击上下文?

时间:2019-04-02 23:17:45

标签: python command-line-interface python-click

我正在尝试使用Python单击创建cli应用程序,并且我想使用分配给click.core.Context.obj的函数作为选项的回调函数。我用作回调函数的函数是根据输入生成的,因此无法导入该函数。

这是我的代码:

该类将分配给上下文:

class Config:
    def __init__(self, func_name):
        self.function = getattr(Config, func_name)

    def func_a():
        pass

    def func_b():
        pass

命令:

import click


@click.group(name='group')
@click.option('-f', '--func-name')
@pass_context
def the_group(ctx, func_name):
    ctx.obj = Config(func_name)


@click.command('command')
@click.option('-o', '--my-option', callback=ctx.obj.function) # I want to use the function here
@click.pass_context
def the_command(ctx, my_option):
    click.echo(my_option)

我在上面的代码中使用的回调函子不起作用。调用ctx.obj.function的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

我建议将@staticmethod添加到您的Config类中,以用作callback的目标,例如:

回调方法:

@staticmethod
def click_callback(ctx, param, value):
    getattr(ctx.obj, ctx.obj.func_name)()
    return value

测试代码:

import click

class Config:
    def __init__(self, func_name):
        self.func_name = func_name

    def func_a(self):
        click.echo('Func A')

    def func_b(self):
        click.echo('Func B')

    @staticmethod
    def click_callback(ctx, param, value):
        getattr(ctx.obj, ctx.obj.func_name)()
        return value


@click.group()
@click.option('-f', '--func-name', required=True)
@click.pass_context
def group(ctx, func_name):
    ctx.obj = Config(func_name)


@group.command()
@click.option('--my-option', '-o', callback=Config.click_callback)
def command(my_option):
    click.echo('command: {}'.format(my_option))


if __name__ == "__main__":
    commands = (
        '-f func_a command -o optionA',
        '-f func_b command -o optionB',
        '-f func_a command -o ',
        'command',
        '--help',
        '',
    )

    import sys, time

    time.sleep(1)
    print('Click Version: {}'.format(click.__version__))
    print('Python Version: {}'.format(sys.version))
    for cmd in commands:
        try:
            time.sleep(0.1)
            print('-----------')
            print('> ' + cmd)
            time.sleep(0.1)
            group(cmd.split())

        except BaseException as exc:
            if str(exc) != '0' and \
                    not isinstance(exc, (click.ClickException, SystemExit)):
                raise

结果:

Click Version: 6.7
Python Version: 3.6.3 (v3.6.3:2c5fed8, Oct  3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)]
-----------
> -f func_a command -o optionA
Func A
command: optionA
-----------
> -f func_b command -o optionB
Func B
command: optionB
-----------
> -f func_a command -o 
Error: -o option requires an argument
-----------
> command
Usage: test.py [OPTIONS] COMMAND [ARGS]...

Error: Missing option "-f" / "--func-name".
-----------
> --help
Usage: test.py [OPTIONS] COMMAND [ARGS]...

Options:
  -f, --func-name TEXT  [required]
  --help                Show this message and exit.

Commands:
  command
-----------
> 
Usage: test.py [OPTIONS] COMMAND [ARGS]...

Options:
  -f, --func-name TEXT  [required]
  --help                Show this message and exit.

Commands:
  command