2

I have many functions that use the same decorators. Is there a way to put all of them in one, and then just apply one across all the functions?

AXE Labs
  • 4,051
  • 4
  • 29
  • 29
  • This is a duplicate of https://stackoverflow.com/questions/5409450/can-i-combine-two-decorators-into-a-single-one-in-python# – AXE Labs May 12 '18 at 12:51

1 Answers1

5

It took me a while, but I've figured it out. Here is an example:

import click

@click.group()
def cli():
  pass

@cli.command()
@click.option('--number', help='Integer number')
@click.option('--letter', help='Single character')
def show(number, letter):
  print "number {} and letter {}".format(number, letter)

@cli.command()
@click.option('--number', help='Integer number')
@click.option('--letter', help='Single character')
def flip(number, letter):
  print "flipped number {} and letter {}".format(-int(number), letter.swapcase())

if __name__ == '__main__':
    cli()

You can decorate all your commands with one decorator that will apply all the other ones like such:

import click, functools

def the_one(f):
  @cli.command()
  @click.option('--number', help='Integer number')
  @click.option('--letter', help='Single character')
  @functools.wraps(f)
  def wrapper(*args, **kwds):
    return f(*args, **kwds)
  return wrapper

@click.group()
def cli():
  pass

@the_one
def show(number, letter):
  print "number {} and letter {}".format(number, letter)

@the_one
def flip(number, letter):
  print "flipped number {} and letter {}".format(-int(number), letter.swapcase())

if __name__ == '__main__':
    cli()

Here it is in action:

$ python example.py flip --number 2 --letter B
flipped number -2 and letter b
AXE Labs
  • 4,051
  • 4
  • 29
  • 29