Applying the validate_attributes Decorator
Now that we have a basic understanding of the validate_attributes
decorator, let's explore how to apply it in different scenarios.
Validating Primitive Types
The most common use case for the validate_attributes
decorator is to validate primitive data types, such as strings, integers, and booleans. Here's an example:
@validate_attributes
class Person:
name: str
age: int
is_adult: bool
person = Person()
person.name = "John"
person.age = 30
person.is_adult = True
## This will raise a ValueError
person.age = "thirty"
In this example, the Person
class has three attributes: name
(a string), age
(an integer), and is_adult
(a boolean). The validate_attributes
decorator ensures that these attributes are set with the correct data types.
Validating Complex Types
The validate_attributes
decorator can also be used to validate more complex data types, such as lists, dictionaries, or custom classes. Here's an example:
from typing import List, Dict
@validate_attributes
class Book:
title: str
authors: List[str]
metadata: Dict[str, str]
book = Book()
book.title = "The Great Gatsby"
book.authors = ["F. Scott Fitzgerald"]
book.metadata = {"genre": "fiction", "publication_year": "1925"}
## This will raise a ValueError
book.authors = ["F. Scott Fitzgerald", 42]
In this example, the Book
class has three attributes: title
(a string), authors
(a list of strings), and metadata
(a dictionary of string-string pairs). The validate_attributes
decorator ensures that these attributes are set with the correct data types.
Combining with Other Decorators
The validate_attributes
decorator can be combined with other decorators to add additional functionality to your classes. For example, you can use it in conjunction with a logging decorator to log attribute changes:
def log_attribute_changes(cls):
class LoggedClass(cls):
def __setattr__(self, name, value):
print(f"Setting attribute '{name}' to '{value}'")
super().__setattr__(name, value)
return LoggedClass
@validate_attributes
@log_attribute_changes
class Person:
name: str
age: int
person = Person()
person.name = "John" ## This will print: "Setting attribute 'name' to 'John'"
person.age = 30 ## This will print: "Setting attribute 'age' to '30'"
By combining the validate_attributes
decorator with the log_attribute_changes
decorator, you can ensure that your class attributes are both validated and their changes are logged.