8:インデックス番号に意味を持たせない¶
Pythonでリストやタプルの インデックス番号 を使ったほうが良いプログラムになる場合は、非常に稀です。 インデックス番号に意味を持たせてしまうとどうなるでしょうか?
具体的な失敗¶
from .item import item_exists
def validate_sales(row):
"""
rowは売上を表すタプル
1要素目: 売上ID
2要素目: 商品ID
3要素目: ユーザーID
4要素目: 個数
5要素目: 売上日時
"""
# IDのチェック
if not item_exists(row[1]):
raise ...
# 個数のチェック
if row[3] < 1:
raise ...
たとえば辞書であれば row['item_id']
のように、処理そのものが意味を表してくれます。
しかしこの例では処理の中で row
のインデックス番号が意味を持っているので、プログラムが読みにくくなっています。
プログラムを読んでいるときに row[1]
が商品IDであると覚えておかないといけません。
またインデックス番号で処理すると、間に新しい値が入ると処理が壊れます。
たとえば row
の仕様が変わって2要素目に「販売店ID」が入るようになったとすると、それ以降の要素を指定する処理を書き換える必要があります。
その場合は、 row[3]
を row[4]
にする必要があります。
ベストプラクティス¶
タプルで管理せず辞書やクラスにしましょう。
row
のタプルを Sale
というクラスに置き換えると、 validate_sales
関数がとても読みやすくなります。
@dataclass
class Sale:
sale_id: int
item_id: int
user_id: int
amount: int
sold_at: datetime
def validate_sales(sale):
""" 売上 sale が不正なデータの場合エラーを送出する
"""
if not item_exists(sale.item_id):
raise ...
if sale.amount < 1:
raise ...
(中略)詳細は書籍 自走プログラマー をご参照ください