Is there a way to define macro-like code to use inside many functions which handle the same data (arguments of the same nature with the same name)? I have many function like "f" below (almost the same interface, they do different things, on the same kind of data). And I have to repeat the same argument validation code for each one.
def f(arg1, arg2, ...):
# validation code
# it checks and eventually change arg1, arg2, etc.
# function code
Is there a way to define a "validation_macro" and then do something like this?
def f(arg1, arg2, ...):
# expand validation_macro
# function code
>Solution :
Yes, you can achieve this in Python using decorators. Decorators allow you to wrap a function with another function, enabling you to add common validation or preprocessing steps to multiple functions without repeating the code. Here’s how you can define a validation decorator and apply it to your functions:
Define a Validation Decorator
First, define a decorator function that performs the validation logic. The decorator can modify the arguments (arg1, arg2, etc.) if needed before passing them to the decorated function:
def validation_decorator(func):
def wrapper(*args, **kwargs):
# Validation code
# Example: Ensure arg1 is positive
if args[0] <= 0:
raise ValueError("arg1 must be positive")
# You can modify args or kwargs here if needed
# Example: Convert arg2 to uppercase
args = list(args)
if isinstance(args[1], str):
args[1] = args[1].upper()
# Call the original function with validated arguments
return func(*args, **kwargs)
return wrapper
Apply the Decorator to Your Functions
Now, apply the validation_decorator to each of your functions (f1, f2, etc.) that require the same validation logic:
@validation_decorator
def f1(arg1, arg2):
# Function code for f1
print(f"f1: arg1={arg1}, arg2={arg2}")
@validation_decorator
def f2(arg1, arg2, arg3):
# Function code for f2
print(f"f2: arg1={arg1}, arg2={arg2}, arg3={arg3}")
# Example usage
f1(5, 'hello') # Output: f1: arg1=5, arg2=HELLO
f2(-3, 'world', 10) # Raises ValueError: arg1 must be positive
This approach helps you keep your validation logic centralized and reusable across multiple functions, reducing code duplication and ensuring consistent handling of function arguments. Adjust the validation logic inside validation_decorator as per your specific requirements for each function.