12:辞書でなくクラスを定義する¶
クラスを作るのに抵抗感がありませんか? 積極的にクラスを定義する利点と、辞書で処理し続ける問題は何でしょうか。
具体的な失敗¶
import json
from datetime import date
def get_fullname(user):
return user['last_name'] + user['first_name']
def calc_age(user):
today = date.today()
born = user['birthday']
age = today.year - born.year
if (today.month, today.day) < (born.month, born.day):
return age - 1
else:
return age
def load_user():
with open('./user.json', encoding='utf-8') as f:
return json.load(f)
この処理の問題は get_fullname
などの関数が「ユーザー」という意味を持つ辞書を期待していることです。
関数が「 特定のキーをもつ辞書 」に縛られるので、他の形式の辞書を渡しても正しく動作しません。
関数にするのであれば、辞書でなく個別の引数として期待するべきです( 7:コレクションを引数にせずintやstrを受け取る 参照)。
ベストプラクティス¶
特定のキーを持つ辞書を期待するなら、クラスを定義しましょう。
import json
from dataclasses import dataclass
from datetime import date
@dataclass
class User:
last_name: str
first_name: str
birthday: date
# 解説:
# クラスにすることで、それぞれの処理をクラスのメソッドやプロパティーとして実装できます。
# ``user.fullname`` のように簡潔にプログラムを書けます。
@property
def fullname(self):
return self.last_name + self.first_name
@property
def age(self):
today = date.today()
born = self.birthday
age = today.year - born.year
if (today.month, today.day) < (born.month, born.day):
return age - 1
else:
return age
def load_user():
with open('./user.json', encoding='utf-8') as f:
return User(**json.load(f))
(中略)詳細は書籍 自走プログラマー をご参照ください