Advanced Usage Patterns
Conditional Default Values
def configure_connection(host='localhost', port=None):
## Dynamic default port based on host
if port is None:
port = 8000 if host == 'localhost' else 5432
return f"Connecting to {host}:{port}"
Function Decorators with Optional Parameters
def optional_debug(enabled=False):
def decorator(func):
def wrapper(*args, **kwargs):
if enabled:
print(f"Calling {func.__name__}")
return func(*args, **kwargs)
return wrapper
return decorator
@optional_debug(enabled=True)
def process_data(data):
return data * 2
Type Hinting with Optional Parameters
from typing import Optional
def user_profile(
name: str,
age: Optional[int] = None,
email: Optional[str] = None
) -> dict:
return {
'name': name,
'age': age,
'email': email
}
Parameter Validation Strategies
def validate_parameters(func):
def wrapper(*args, **kwargs):
## Custom validation logic
if any(arg is None for arg in args):
raise ValueError("No None values allowed")
return func(*args, **kwargs)
return wrapper
@validate_parameters
def complex_calculation(x, y, z=10):
return x * y + z
Advanced Optional Parameter Patterns
Pattern |
Description |
Use Case |
Sentinel Objects |
Unique default values |
Distinguishing between unset and default |
Lazy Evaluation |
Compute default on-the-fly |
Resource-intensive defaults |
Callback Defaults |
Function as default value |
Dynamic default generation |
Lazy Default Value Generation
import time
def get_timestamp():
return time.time()
def log_event(message, timestamp=None):
timestamp = timestamp or get_timestamp()
print(f"Event: {message} at {timestamp}")
Sentinel Object Pattern
_UNSET = object()
def configure_settings(debug=_UNSET):
if debug is _UNSET:
debug = False
## Configuration logic
return {'debug': debug}
Dependency Injection with Optional Parameters
graph TD
A[Function Call] --> B{Dependency Provided?}
B -->|Yes| C[Use Provided Dependency]
B -->|No| D[Use Default/Injected Dependency]
Complex Optional Parameter Example
class DatabaseConnection:
def __init__(
self,
host='localhost',
port=5432,
username=None,
password=None
):
self.connection_string = self._build_connection(
host, port, username, password
)
def _build_connection(self, host, port, username, password):
## Complex connection string generation
auth = f"{username}:{password}@" if username else ""
return f"postgres://{auth}{host}:{port}/database"
- Minimize complex default value computations
- Use type hints for clarity
- Prefer explicit over implicit defaults
- Document optional parameter behaviors
By exploring these advanced patterns, developers using LabEx can create more sophisticated and flexible Python functions with optional parameters.