是否可以将python @ click.option装饰器重复用于多个命令?

Gar*_*ohn 11 python python-click

我有两个Python CLI工具,它们共享一组常用的click.options。目前,通用选项已重复:

@click.command()
@click.option('--foo', is_flag=True)
@click.option('--bar', is_flag=True)
@click.option('--unique-flag-1', is_flag=True)
def command_one():
    pass

@click.command()
@click.option('--foo', is_flag=True)
@click.option('--bar', is_flag=True)
@click.option('--unique-flag-2', is_flag=True)
def command_two():
    pass
Run Code Online (Sandbox Code Playgroud)

是否可以将通用选项提取到可以应用于每个功能的单个装饰器中?

Wil*_*den 19

您可以构建自己的装饰器来封装常用选项:

def common_options(function):
    function = click.option('--unique-flag-1', is_flag=True)(function)
    function = click.option('--bar', is_flag=True)(function)
    function = click.option('--foo', is_flag=True)(function)
    return function

@click.command()
@common_options
def command():
    pass
Run Code Online (Sandbox Code Playgroud)


hot*_*nov 18

如果您想保留 click 的选项装饰器语法,您可以通过以下方式实现您的装饰器:

import functools

def common_options(f):
    @click.option('--foo', is_flag=True)
    @click.option('--bar', is_flag=True)
    @functools.wraps(f)
    def wrapper_common_options(*args, **kwargs):
        return f(*args, **kwargs)

    return wrapper_common_options


@click.command()
@common_options
@click.option('--unique-flag-1', is_flag=True)
def command_one():
    pass
Run Code Online (Sandbox Code Playgroud)


小智 9

这是一个装饰器,它使用与之前答案相同的原理:

def group_options(*options):
    def wrapper(function):
        for option in reversed(options):
            function = option(function)
        return function
    return wrapper

opt_1 = click.option("--example1")
opt_2 = click.option("--example2")
opt_3 = click.option("--example3")

@cli.command()
@click.option("--example0")
@group_options(opt_1, opt_2, opt_3)
def command(example0, example1, example2, example3):
    pass
Run Code Online (Sandbox Code Playgroud)