In Python, if you want to validate all class attributes using a class validator, you can use the Pydantic library, which provides powerful data validation capabilities, or use Python's standard library such as dataclasses combined with type hints and custom validation functions. Here are examples of using both methods:
Method 1: Using Pydantic
Pydantic is a library for data validation and settings management, which can be used to define data models and automatically handle type enforcement and validation.
pythonfrom pydantic import BaseModel, ValidationError, validator class User(BaseModel): name: str age: int email: str @validator('*') def check_all_fields(cls, value, field): if field.name == 'name' and not value.isalpha(): raise ValueError('Name must only contain alphabets') if field.name == 'age' and not (0 < value < 100): raise ValueError('Age must be between 1 and 99') if field.name == 'email' and '@' not in value: raise ValueError('Email must contain @') return value # Example usage try: user = User(name="John Doe", age=30, email="john@example.com") print(user) except ValidationError as e: print(e)
In this example, @validator('*') is used to indicate that the validator applies to all fields. Each field is validated by the check_all_fields function, with different rules applied based on the field name.
Method 2: Using dataclasses and custom validation functions
If you are using Python's standard library dataclasses, you can manually implement attribute validation:
pythonfrom dataclasses import dataclass, field from typing import Any def validate_name(name: str) -> str: if not name.isalpha(): raise ValueError("Name must only contain alphabets") return name def validate_age(age: int) -> int: if not (0 < age < 100): raise ValueError("Age must be between 1 and 99") return age def validate_email(email: str) -> str: if '@' not in email: raise ValueError("Email must contain @") return email @dataclass class User: name: str = field(metadata={"validate": validate_name}) age: int = field(metadata={"validate": validate_age}) email: str = field(metadata={"validate": validate_email}) def __post_init__(self): for field_name, field_def in self.__dataclass_fields__.items(): validator = field_def.metadata.get("validate", None) if validator: setattr(self, field_name, validator(getattr(self, field_name))) # Example usage try: user = User(name="John Doe", age=30, email="john@example.com") print(user) except ValueError as e: print(e)
In this method, validation functions are defined for each field and called during the __post_init__ method, enabling immediate validation after instance creation.
Both methods have their advantages. Using Pydantic simplifies comprehensive data validation, while using dataclasses aligns with Python's standard library conventions and facilitates integration with other standard modules. The choice depends on project requirements and personal preference.