到達点は、入力、出力、許される範囲を決めて関数を書くことです。前提は第02回です。
関数に一つの判断を任せる
送料を求める関数なら、購入額を受け取り、送料を返すと決めます。表示や入力まで同じ関数に詰め込まなければ、別の画面やテストから再利用できます。defの後のインデントが関数の範囲です。
def shipping(amount, *, member=False):
if amount < 0:
raise ValueError("購入額は0以上です")
threshold = 3000 if member else 5000
return 0 if amount >= threshold else 500
total = 0
for index, amount in enumerate([0, 4999, 5000], start=1):
fee = shipping(amount)
total += fee
print(index, amount, fee)
print("送料合計:", total)
print("会員の送料:", shipping(3000, member=True))
main.pyとして実行すると、送料は500、500、0、合計1000、会員の送料は0です。星印の後のmemberはキーワードで渡す引数なので、shipping(3000, True) は受け付けません。意味の見えにくい真偽値の引数に有効です。
境界とスコープ
rangeの終端は含みません。range(3) は0、1、2です。forは繰り返し可能な値から要素を順に取り出します。whileは条件が真の間続きます。breakはループを終え、continueは次の反復へ進みます。
関数内で代入した名前は原則ローカルです。戻り値を使って外へ結果を渡す方が、グローバル変数を何か所からも変えるより追跡しやすくなります。returnを省略した関数の戻り値はNoneです。
デフォルト引数の値は、呼び出すたびではなく関数定義時に評価されます。def add(item, items=[]): のような可変値は呼び出し間で共有されます。毎回新しいリストが必要ならデフォルトをNoneにし、関数の中で生成します。
練習と解答
練習:itemsを省略したときだけ新しいリストを作るadd関数を書いてください。
解答例:def add(item, items=None): とし、本文で if items is None: items = []、続けてappendし、itemsを返します。if not items では、呼び出し元が渡した空リストも置き換えてしまうので契約が変わります。
卒業チェック:0、閾値の直前、閾値、負の値を挙げ、期待結果を実行前に言えるか確認します。
公式資料
制御フローと関数を参照できます。
Python全20回の目次 | 前の回 | 次の回