How to Validate User Input with a Dataclass in Python
A dataclass stores name, age, and email, and a validator class checks each field, returning a dictionary of boolean results.
Python code
40 linesfrom dataclasses import dataclass
@dataclass
class UserInput:
name: str
age: int
email: str
def is_valid_name(self) -> bool:
return bool(self.name.strip()) and len(self.name.strip()) >= 2
def is_valid_age(self) -> bool:
return isinstance(self.age, int) and 0 < self.age < 150
def is_valid_email(self) -> bool:
return "@" in self.email and self.email.count("@") == 1
class InputValidator:
def __init__(self, data: UserInput):
self.data = data
def validate(self) -> dict:
checks = {
"name": self.data.is_valid_name(),
"age": self.data.is_valid_age(),
"email": self.data.is_valid_email(),
}
return checks
def is_all_valid(self) -> bool:
return all(self.validate().values())
if __name__ == "__main__":
sample = UserInput(name="Alice", age=25, email="alice@example.com")
validator = InputValidator(sample)
print(validator.validate())
print(f"All valid: {validator.is_all_valid()}")
Output
{'name': True, 'age': True, 'email': True}
All valid: True
How it works
The @dataclass decorator automatically generates __init__, __repr__, and equality methods, so you only define attributes and methods. Each is_valid_* method encapsulates a single rule, keeping the validation logic close to the data. The InputValidator class uses composition, holding a UserInput instance and exposing validate() and is_all_valid() for a clean API.
Common mistakes
- Forgetting to strip whitespace before checking name length
- Not checking that age is an integer, allowing strings to pass
- Counting '@' occurrences to ensure exactly one, but forgetting empty email
Variations
- Use `@dataclass(frozen=True)` to make instances immutable
- Add a `__post_init__` method to validate at creation time
Real-world use cases
- Validating form submissions in a web app before saving to a database.
- Sanitizing user input from a CLI tool before processing.
- Checking API request payloads against expected types and constraints.
Sponsored
More from OOP & classes
- Add property getter setter validation in Python easy
- Binary Tree Inorder Traversal in Python easy
- Borg pattern shared state in Python medium
- Bridge Pattern in Python: Separate Abstraction from Implementation medium
- Composable Predicates with the &, |, ~ Operators in Python medium
- Composition over Inheritance: How to Build a Wallet Account in Python easy
Keep learning
Related tutorials and quizzes for this topic.