4-2
引数への再代入をやめる
受け取った引数に別の意味の値を上書きすると、その行以降は変数名が嘘をつき始める。「申請額」という名前の変数に合計額が入っている、という食い違いは読み手の予想を裏切り、ログや後続の計算で静かに事故を起こす。引数は読み取り専用とみなし、別の意味の値には新しい変数を立てる。
経費申請の月次上限チェック
✕ Bad
MONTHLY_LIMIT = 300_000
def accept_expense(amount: int, monthly_total: int) -> None:
# 申請額だったはずの amount が、ここから先は累計額になる
amount = monthly_total + amount
if MONTHLY_LIMIT < amount:
raise ValueError("月次の経費上限を超えています")
# 申請額のつもりで累計額が表示されてしまう
print(f"申請額 {amount:,} 円を受け付けました")✓ Good
MONTHLY_LIMIT = 300_000
def accept_expense(amount: int, monthly_total: int) -> None:
projected_total = monthly_total + amount
if MONTHLY_LIMIT < projected_total:
raise ValueError("月次の経費上限を超えています")
print(f"申請額 {amount:,} 円を受け付けました")Java では引数に final を付けて再代入そのものを禁止できる。Python では機械的に止める手段がないぶん、「引数には代入しない」を習慣として徹底する。引数を加工したくなったら、それは別の概念が生まれたサインなので新しい名前を付ける。