I know this is not how decorators are intended but..
I have decorators to save various outpust from functions to xlsx, csv, other
what I want to do is
@save_xlsx
@save_csv
def whatever_function():
and have one file saved in .xlsx and the other in .csv, both working with the same output from whatever_function()
. I also want to be able to use only one decorator on other functions.
Or maybe this is not the right approach?
This kinda reminds me of monads. Anyway, you can make a transparent generic logging decorator:
def log(callback):
def logger(fn):
def logwrapper(*args, **kwargs):
value = fn(*args, **kwargs)
callback(value)
return value
return logwrapper
return logger
csv_callback = lambda x: print('writing {} to a csv file'.format(x))
xlsx_callback = lambda x: print('writing {} to an xlsx file'.format(x))
@log(csv_callback)
@log(xlsx_callback)
def test(a, b):
return a + b
In [2]: test(1, 2)
writing 3 to an xlsx file
writing 3 to a csv file
Out[2]: 3
In [3]: test(2, 3)
writing 5 to an xlsx file
writing 5 to a csv file
Out[3]: 5
You can also just pass several callbacks into the logger to avoid excessive nesting
def log(*callbacks):
def logger(fn):
def logwrapper(*args, **kwargs):
value = fn(*args, **kwargs)
for callback in callbacks:
callback(value)
return value
return logwrapper
return logger
@log(csv_callback, xlsx_callback)
def test(a, b):
return a + b