mirror of
https://github.com/Brandon-Rozek/website.git
synced 2024-11-09 10:40:34 -05:00
New post
This commit is contained in:
parent
bb074f4820
commit
11941f521e
1 changed files with 69 additions and 0 deletions
69
content/blog/python-dataclasses-derived-fields-validation.md
Normal file
69
content/blog/python-dataclasses-derived-fields-validation.md
Normal file
|
@ -0,0 +1,69 @@
|
|||
---
|
||||
title: "Python Dataclasses: Derived Fields and Validation"
|
||||
date: 2024-01-15T11:02:21-05:00
|
||||
draft: false
|
||||
tags: []
|
||||
math: false
|
||||
medium_enabled: false
|
||||
---
|
||||
|
||||
Python dataclasses provide a simplified way of creating simple classes that hold data.
|
||||
|
||||
```python
|
||||
from dataclasses import dataclass
|
||||
|
||||
@dataclass
|
||||
class Person:
|
||||
name: str
|
||||
birth_year: int
|
||||
```
|
||||
|
||||
The above code is equivalent to:
|
||||
|
||||
```python
|
||||
class A:
|
||||
def __init__(name: str, birth_year: int):
|
||||
self.name = name
|
||||
self.birth_year = birth_year
|
||||
self.__post__init__()
|
||||
```
|
||||
|
||||
Notice the call to `__post__init__` at the end. We can override that method to do whatever we'd like. I have found two great use cases for this.
|
||||
|
||||
## Use Case 1: Derived Fields
|
||||
|
||||
Straight from the [Python documentation](https://docs.python.org/3/library/dataclasses.html#dataclasses.__post_init__), this use case is for when we want to use some variables to create a new variable.
|
||||
|
||||
For example, to compute a new field `age` from a person's `birth_year`:
|
||||
|
||||
```python
|
||||
class Person:
|
||||
name: str
|
||||
birth_year: int
|
||||
age: int = field(init=False)
|
||||
|
||||
def __post_init__(self):
|
||||
# Assuming the current year is 2024 and their birthday already passed
|
||||
self.age = 2024 - self.birth_year
|
||||
```
|
||||
|
||||
## Use Case 2: Validation
|
||||
|
||||
Another use case is to make sure
|
||||
that the user instantiates the fields
|
||||
of a data class in a way we expect.
|
||||
|
||||
|
||||
```python
|
||||
class Person:
|
||||
name: str
|
||||
birth_year: int
|
||||
|
||||
def __post__init__(self):
|
||||
assert self.birth_year > 0
|
||||
assert isinstance(self.name, str)
|
||||
```
|
||||
|
||||
|
||||
Nothing is stopping us from combining both of these use cases within the `__post_init__` method!
|
||||
|
Loading…
Reference in a new issue