==================================== 8:インデックス番号に意味を持たせない ==================================== Pythonでリストやタプルの :index:`インデックス番号` を使ったほうが良いプログラムになる場合は、非常に稀です。 インデックス番号に意味を持たせてしまうとどうなるでしょうか? 具体的な失敗 ================== .. code:: 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`` 関数がとても読みやすくなります。 .. code:: python @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 ... .. omission::