mirror of
https://github.com/Brandon-Rozek/website.git
synced 2025-05-28 22:57:29 +00: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…
Add table
Reference in a new issue