14:別メソッドに値を渡すためだけに属性を設定しない¶
クラスはとても有効ですが、 self
の扱い方を間違えるとクラス内の処理が読みにくくなります。
たとえば、次の例を見てください。
具体的な失敗¶
from datetime import date
class User:
def __init__(self, username, birthday):
self.username = username
self.birthday = birthday
self.age = None
def calc_age(self):
today = date.today()
age = (self.birthday - today).years
if (self.birthday.month, self.birthday.day) < (today.month, today.day):
age -= 1
self.age = age
def age_display(self):
return f"{self.age}歳"
このクラスでは self.age
属性を介して、 age_display
メソッドが calc_age
に依存しています。
calc_age
メソッドの前に age_display
を呼び出してしまうと "None歳"
という文字が返されてしまいます。
__init__
内で calc_age
を呼び出すようにした場合も、 birthday
を変更すると calc_age
を呼び出す必要があります。
そもそも「事前に他のメソッドを呼び出す必要がある」という設計にするのが良くありません。
ベストプラクティス¶
別のメソッドに値を渡すためだけに属性を設定するのはやめましょう。
from datetime import date
class User:
def __init__(self, username, birthday):
self.username = username
self.birthday = birthday
@property
def age(self):
today = date.today()
age = (self.birthday - today).years
if (self.birthday.month, self.birthday.day) < (today.month, today.day):
age -= 1
return age
def age_display(self):
return f"{self.age}歳"
age
を属性という状態にするのでなくて、 @property
に実装するほうが良いです。
変数や属性という「状態」を減らすことで、考えるべきこと、覚えておくべきことが減らせるからです。
(中略)詳細は書籍 自走プログラマー をご参照ください