Practical Type Validation
Real-World Type Validation Techniques
Decorator-Based Type Validation
def validate_types(*types):
def decorator(func):
def wrapper(*args, **kwargs):
for arg, expected_type in zip(args, types):
if not isinstance(arg, expected_type):
raise TypeError(f"Expected {expected_type}, got {type(arg)}")
return func(*args, **kwargs)
return wrapper
return decorator
@validate_types(int, str)
def process_data(number, text):
return f"{text}: {number * 2}"
## Usage examples
print(process_data(5, "Result")) ## Valid
## process_data("5", "Result") ## Raises TypeError
Type Validation Patterns
graph TD
A[Type Validation] --> B[Input Validation]
A --> C[Data Transformation]
A --> D[Error Handling]
Comprehensive Type Checking Strategy
Validation Approach |
Use Case |
Example |
isinstance() |
Simple type checking |
isinstance(x, int) |
Type Hints |
Static type annotation |
def func(x: int) -> str: |
Custom Validators |
Complex type rules |
Custom decorator validation |
Advanced Type Validation Class
class TypeValidator:
@staticmethod
def validate(value, expected_type, allow_none=False):
if allow_none and value is None:
return True
if not isinstance(value, expected_type):
raise TypeError(f"Invalid type. Expected {expected_type}, got {type(value)}")
return True
@staticmethod
def validate_collection(collection, item_type):
return all(isinstance(item, item_type) for item in collection)
## Usage
def process_user_data(user_id: int, username: str):
TypeValidator.validate(user_id, int)
TypeValidator.validate(username, str)
## Process data
return f"User {username} with ID {user_id}"
Practical Validation Scenarios
1. Configuration Validation
def validate_config(config):
required_keys = ['host', 'port', 'database']
for key in required_keys:
if key not in config:
raise ValueError(f"Missing required configuration: {key}")
if key == 'port' and not isinstance(config['port'], int):
raise TypeError("Port must be an integer")
## Example usage
config = {
'host': 'localhost',
'port': 5432,
'database': 'labex_db'
}
validate_config(config)
- Use type validation strategically
- Minimize runtime type checking
- Leverage type hints
- Create reusable validation utilities
Error Handling Strategies
def safe_type_conversion(value, target_type):
try:
return target_type(value)
except (ValueError, TypeError) as e:
print(f"Conversion error: {e}")
return None
By implementing these practical type validation techniques, developers using LabEx can create more robust and reliable Python applications with comprehensive type checking mechanisms.