I made an example. The wraps function just copies the docstring and some other stuff to the decorated function.
from functools import wraps
def decorator(*decorator_args, color="green", size=12, **decorator_kwargs):
def wrapper(func):
@wraps(func)
def inner(*args, **kwargs):
print("DEBUG OUTPUT")
print(
f"Deco args : {decorator_args}",
f"Deco kwargs : {decorator_kwargs}",
f"Func : {func}",
f"args : {args}",
f"kwargs : {kwargs}",
sep="\n",
)
print("====================")
return func(*args, **kwargs)
return inner
if len(decorator_args) == 1 and callable(decorator_args[0]):
return wrapper(decorator_args[0])
else:
return wrapper
deco_print1 = decorator(print)
deco_print2 = decorator(1,2,3,4,5, color="red", size=42, foo=1337)(print)
@decorator
def deco_print3(*args, **kwargs):
print(*args, **kwargs)
@decorator(1,2,3,4,5, color="red", size=42, foo=1337)
def deco_print4(*args, **kwargs):
print(*args, **kwargs)
deco_print1("deco_print1")
deco_print3("deco_print3")
deco_print2("deco_print2")
deco_print4("deco_print4")
Output:
DEBUG OUTPUT
Deco args : (<built-in function print>,)
Deco kwargs : {}
Func : <built-in function print>
args : ('deco_print1',)
kwargs : {}
====================
deco_print1
DEBUG OUTPUT
Deco args : (<function deco_print3 at 0x7f7661c04ee0>,)
Deco kwargs : {}
Func : <function deco_print3 at 0x7f7661c04ee0>
args : ('deco_print3',)
kwargs : {}
====================
deco_print3
DEBUG OUTPUT
Deco args : (1, 2, 3, 4, 5)
Deco kwargs : {'foo': 1337}
Func : <built-in function print>
args : ('deco_print2',)
kwargs : {}
====================
deco_print2
DEBUG OUTPUT
Deco args : (1, 2, 3, 4, 5)
Deco kwargs : {'foo': 1337}
Func : <function deco_print4 at 0x7f7661c04280>
args : ('deco_print4',)
kwargs : {}
====================
deco_print4