🛠️
Python の json.load() の結果を dataclass として受け取る方法
環境
Python 3.9
結論
json.load()
の object_hook
というオプション引数を指定してあげれば簡単です。
holidays.json
[
{
"name": "元日",
"date": "2021-01-01"
},
{
"name": "成人の日",
"date": "2021-01-11"
}
]
data.py
from datetime import date
from dataclasses import dataclass
@dataclass
class Holiday:
name: str
date: date
decoder.py
import datetime
from data import Holiday
def decode_holiday(data: dict) -> Holiday:
name = data['name']
tmp_date = datetime.datetime.strptime(data['date'], '%Y-%m-%d')
date = datetime.date(tmp_date.year, tmp_date.month, tmp_date.day)
return Holiday(name=name, date=date)
main.py
import json
from data import Holiday
from decoder import decode_holiday
def print_holidays():
holidays_file = open('holidays.json', 'r')
holidays: [Holiday] = json.load(holidays_file, object_hook=decode_holiday)
print(holidays)
if __name__ == '__main__':
print_holidays()
# [Holiday(name='元日', date=datetime.date(2021, 1, 1)), Holiday(name='成人の日', date=datetime.date(2021, 1, 11))]
追記
pydantic というライブラリを使うと、自動で date 型への変換もやってくれます。
※ Twitter で yu-ichiro さん に教えていただきました
pip install pydantic
data.py
from datetime import date
from pydantic.dataclasses import dataclass
@dataclass
class Holiday:
name: str
date: date
main.py
from typing import List
import pydantic
from data import Holiday
def print_holidays():
holidays: List[Holiday] = pydantic.parse_file_as(List[Holiday], 'holidays.json')
print(holidays)
if __name__ == '__main__':
print_holidays()
# [Holiday(name='元日', date=datetime.date(2021, 1, 1)), Holiday(name='成人の日', date=datetime.date(2021, 1, 11))]
Discussion