Argument Handling Patterns
Defensive Argument Handling
Type Checking
Implement robust type checking to ensure argument validity:
def process_data(data):
if not isinstance(data, (list, tuple)):
raise TypeError("Input must be a list or tuple")
return [x * 2 for x in data]
try:
result = process_data([1, 2, 3])
print(result)
process_data("invalid")
except TypeError as e:
print(e)
Argument Validation
def create_user(username, age):
if not isinstance(username, str):
raise ValueError("Username must be a string")
if not 0 < age < 120:
raise ValueError("Invalid age range")
return {"username": username, "age": age}
Default Value Handling
def configure_settings(config=None):
default_config = {
'debug': False,
'log_level': 'INFO',
'timeout': 30
}
return {**default_config, **(config or {})}
## LabEx recommended configuration pattern
settings = configure_settings({'debug': True})
print(settings)
Advanced Argument Patterns
Decorator for Argument Validation
def validate_arguments(func):
def wrapper(*args, **kwargs):
## Custom validation logic
if len(args) > 3:
raise ValueError("Too many arguments")
return func(*args, **kwargs)
return wrapper
@validate_arguments
def example_function(a, b, c=None):
return a + b
Argument Handling Strategy
flowchart TD
A[Argument Input] --> B{Validate Type}
B -->|Valid| C{Apply Defaults}
B -->|Invalid| D[Raise Exception]
C --> E{Transform}
E --> F[Process Function]
Common Argument Handling Techniques
Technique |
Description |
Example |
Type Checking |
Verify argument types |
isinstance(arg, type) |
Default Values |
Provide fallback values |
def func(x=None) |
Argument Unpacking |
Flexible argument passing |
func(*args, **kwargs) |
Validation Decorators |
Add pre-processing checks |
@validate_arguments |
Error Handling Strategies
Graceful Degradation
def safe_division(a, b, default=None):
try:
return a / b
except ZeroDivisionError:
return default
except TypeError:
return None
print(safe_division(10, 2)) ## Normal division
print(safe_division(10, 0)) ## Returns None
def transform_arguments(func):
def wrapper(*args, **kwargs):
## Transform arguments before calling function
transformed_args = [str(arg).strip() for arg in args]
transformed_kwargs = {k: str(v).strip() for k, v in kwargs.items()}
return func(*transformed_args, **transformed_kwargs)
return wrapper
@transform_arguments
def process_text(text1, text2):
return f"{text1} {text2}"
By mastering these argument handling patterns, you'll create more robust and flexible Python functions in your LabEx development projects.