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(..., ...)
.