Search code examples
pythonpython-2.7python-click

exactly same options for 2 different functions in python click


I'm writing a tool using Python 2 and click which reads/writes registers in hardware. I have two functions that accept exactly the same options. The difference is that they process input and direct output to a different devices.

Here is what I have so far:

@cli.command()
@click.option('--r0', type=click.IntRange(-2, 0xffffffff, clamp=False), default=-2)
@click.option('--r1', type=click.IntRange(-2, 0xffffffff, clamp=False), default=-2)
@click.option('--r2', type=click.IntRange(-2, 0xffffffff, clamp=False), default=-2)
def mydevice1(r0, r1, r2):
    # Handle inputs for device 1
    click.echo('myfunc1')

@cli.command()   
@click.option('--r0', type=click.IntRange(-2, 0xffffffff, clamp=False), default=-2)
@click.option('--r1', type=click.IntRange(-2, 0xffffffff, clamp=False), default=-2)
@click.option('--r2', type=click.IntRange(-2, 0xffffffff, clamp=False), default=-2)
def mydevice2(r0, r1, r2):
    # Handle inputs for device 2
    click.echo('myfunc2')

Both of the functions will handle inputs in the same way, the only difference is that they will pass handled info to different devices. In other words what I'd like to have is

@click.option('--r0', type=click.IntRange(-2, 0xffffffff, clamp=False), default=-2)
@click.option('--r1', type=click.IntRange(-2, 0xffffffff, clamp=False), default=-2)
@click.option('--r2', type=click.IntRange(-2, 0xffffffff, clamp=False), default=-2)
def handle_common_options(r0, r1, r2):
    # Handle common options
    pass

@cli.command()
def mydevice1():
    handle_common_options()
    # pass processed options to device 1

@cli.command()
def mydevice2():
    handle_common_options()
    # pass processed options to device 2

Is this possible?


Solution

  • sure.

    @decorator
    def f():
        pass
    

    means

    def f():
        pass
    f = decorator(f)
    

    so:

    decorator0 = cli.command()
    decorator1 = click.option('--r0', type=click.IntRange(-2, 0xffffffff, clamp=False), default=-2)
    decorator2 = click.option('--r1', type=click.IntRange(-2, 0xffffffff, clamp=False), default=-2)
    decorator3 = click.option('--r2', type=click.IntRange(-2, 0xffffffff, clamp=False), default=-2)
    
    common_decorator = lambda f: decorator0(decorator1(decorator2(decorator3(f))))
    
    @common_decorator
    def mydevice1(r0, r1, r2):
        click.echo('myfunc1')
    
    @common_decorator
    def mydevice2(r0, r1, r2):
        click.echo('myfunc2')
    

    without a lambda:

    def common_decorator(f):
        return decorator0(decorator1(decorator2(decorator3(f))))