Decorator that accept multiple input is like dataclasses decorator
In that example, dataclass accept three syntaxes:
@dataclass class C: ... @dataclass() class C: ... @dataclass(init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False, weakref_slot=False) class C: ...
In creating decorator with same behavior, you can use this,
import inspect def customdecorator(*args, **kwargs): def decorator(func): print('input decorator:', args, kwargs) def __wrapper(*func_args, **func_kwargs): print('input decorator inside function:', args, kwargs) print('input function:', func_args, func_kwargs) # Do something before calling the function result = func(*func_args, **func_kwargs) # Do something after calling the function return result return __wrapper print('input root:', args, kwargs) if len(kwargs) > 0: # Decorator is used with arguments, e.g., @functionmethod(arg1=val1, arg2=val2) return decorator if len(args) == 0: return decorator if len(args) == 1: return decorator(args[0]) # Example usages @customdecorator def example1(): print("Function without call") @customdecorator() def example2(): print("Function without arguments") @customdecorator(arg1="value1", arg2="value2") def example3(arg2): print(f"Function with arguments: {arg2}") example1() example2() example3(arg2="ex2")
In your case, it will be
def myDecorator(*args, **kwargs): def decorator(func): def __wrapper(*func_args, **func_kwargs): # Do something before calling the function test_func = kwargs.get('test_func', None) logIt = kwargs.get('logIt', None) if logIt: print("Calling Function: " + test_func.__name__) result = func(*func_args, **func_kwargs) # Do something after calling the function return result return __wrapper if len(kwargs) > 0: # Decorator is used with arguments, e.g., @functionmethod(arg1=val1, arg2=val2) return decorator if len(args) == 0: return decorator if len(args) == 1: return decorator(args[0]) @myDecorator(logIt=False) def someFunc(): print('Hello') someFunc()
The caveat is:
- Optional parameter must use key argument.
- Default value is entered via
kwargs.get(..., ...).