Advanced Default Techniques
Dynamic Default Arguments
Callable Default Values
import time
from datetime import datetime
def log_event(message, timestamp=datetime.now):
return f"{timestamp()} - {message}"
## Dynamic timestamp generation
print(log_event("User login"))
print(log_event("System check"))
Default Argument Techniques
| Technique |
Description |
Use Case |
| Callable Defaults |
Generate values at function call |
Dynamic timestamps |
| Conditional Defaults |
Adapt defaults based on context |
Flexible configurations |
| Type Hinting |
Specify expected default types |
Improved type safety |
Type Hinting with Defaults
from typing import List, Optional
def process_data(
items: List[int] = [],
max_value: Optional[int] = None
) -> List[int]:
if max_value is not None:
return [item for item in items if item <= max_value]
return items
Advanced Default Strategies
flowchart TD
A[Advanced Default Techniques]
A --> B[Callable Defaults]
A --> C[Conditional Initialization]
A --> D[Type-Aware Defaults]
Functional Default Arguments
def create_validator(
min_length: int = 0,
max_length: int = float('inf'),
required_chars: str = ''
):
def validate(value: str) -> bool:
if not (min_length <= len(value) <= max_length):
return False
return all(char in value for char in required_chars)
return validate
## Create specialized validators
password_validator = create_validator(
min_length=8,
required_chars='!@#$%'
)
print(password_validator("Strong!Pass")) ## True
print(password_validator("weak")) ## False
Decorator-Based Default Handling
def default_config(func):
def wrapper(*args, **kwargs):
## Default configuration
default_settings = {
'timeout': 30,
'retries': 3,
'verbose': False
}
## Update with provided arguments
default_settings.update(kwargs)
return func(*args, **default_settings)
return wrapper
@default_config
def connect_service(host, **config):
print(f"Connecting to {host}")
print(f"Configuration: {config}")
## Flexible configuration
connect_service('api.example.com')
connect_service('db.example.com', timeout=60)
flowchart TD
A[Performance Implications]
A --> B[Avoid Complex Defaults]
A --> C[Lazy Evaluation]
A --> D[Minimize Overhead]
Best Practices
- Use
None for complex default initializations
- Prefer lazy evaluation
- Keep default logic simple
- Use type hints for clarity
LabEx Pro Tip
Advanced default techniques can significantly improve function flexibility and readability. Always consider the trade-offs between complexity and maintainability.
Complex Default Argument Example
def configure_system(
debug: bool = False,
log_level: str = 'INFO',
plugins: list = None,
error_handler: callable = print
):
if plugins is None:
plugins = []
return {
'debug': debug,
'log_level': log_level,
'plugins': plugins,
'error_handler': error_handler
}
## Flexible configuration
system_config = configure_system(
debug=True,
plugins=['monitoring', 'security']
)
By mastering these advanced default techniques, you can create more flexible, robust, and maintainable Python functions.