Practical Type Checking
Real-World Type Validation Scenarios
Type checking is crucial in creating robust and reliable Python applications. This section explores practical approaches to type validation in various contexts.
def calculate_area(length: float, width: float) -> float:
## Validate input types before processing
if not isinstance(length, (int, float)) or not isinstance(width, (int, float)):
raise TypeError("Length and width must be numeric values")
return length * width
## Usage examples
try:
print(calculate_area(5, 3)) ## Valid input
print(calculate_area("5", 3)) ## Raises TypeError
except TypeError as e:
print(f"Validation Error: {e}")
Complex Type Validation Patterns
Flexible Type Validation Decorator
def validate_types(*expected_types):
def decorator(func):
def wrapper(*args):
for arg, expected_type in zip(args, expected_types):
if not isinstance(arg, expected_type):
raise TypeError(f"Expected {expected_type}, got {type(arg)}")
return func(*args)
return wrapper
return decorator
## Practical application
@validate_types(str, int)
def create_user_profile(name: str, age: int):
return f"User {name} is {age} years old"
## Usage
try:
print(create_user_profile("LabEx User", 30)) ## Valid
print(create_user_profile(123, "invalid")) ## Raises TypeError
except TypeError as e:
print(f"Validation Error: {e}")
Type Validation Workflow
graph TD
A[Input Received] --> B{Type Validation}
B --> |Valid| C[Process Data]
B --> |Invalid| D[Raise Error]
C --> E[Return Result]
D --> F[Error Handling]
Advanced Type Checking Techniques
Technique |
Use Case |
Complexity |
isinstance() |
Simple type checking |
Low |
Custom Decorators |
Complex type validation |
Medium |
Type Hints |
Static type checking |
Medium |
Runtime Type Checking |
Dynamic validation |
High |
Data Parsing and Conversion
def safe_convert(value, target_type):
try:
## Attempt type conversion with validation
converted = target_type(value)
return converted
except (ValueError, TypeError):
print(f"Cannot convert {value} to {target_type}")
return None
## Practical examples
print(safe_convert("42", int)) ## 42
print(safe_convert("3.14", float)) ## 3.14
print(safe_convert("text", int)) ## None
Type Checking in Data Processing
Handling Mixed Data Types
def process_data_collection(data_list):
validated_data = []
for item in data_list:
if isinstance(item, (int, float)):
validated_data.append(item)
else:
print(f"Skipping invalid item: {item}")
return validated_data
## Example usage
mixed_data = [1, 2, "three", 4.5, [1, 2], 6]
result = process_data_collection(mixed_data)
print(result) ## [1, 2, 4.5, 6]
Best Practices for Type Checking
- Validate inputs early in the function
- Use type hints for documentation
- Implement clear error messages
- Choose appropriate validation method
- Consider performance implications
Error Handling Strategies
def robust_type_validation(func):
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except TypeError as e:
print(f"Type Validation Error: {e}")
## Optional: logging, alternative action
return None
return wrapper
@robust_type_validation
def complex_calculation(x: int, y: int):
return x / y
By mastering these practical type checking techniques, you'll create more reliable and maintainable Python applications in your LabEx projects.