デフォルト引数・キーワード引数・引数の展開
商品価格・個数・送料の関数を使い、同じ値を複数の書き方で渡します。定義時のデフォルト値と、重複指定によるエラーも実行して確認します。
説明
関数の引数は、位置、名前、省略時の値、コレクションの展開によって渡せます。どの仮引数に何が入るかが決まってから、関数本体が動きます。
商品価格・個数・送料の関数を使い、同じ値を複数の書き方で渡します。定義時のデフォルト値と、重複指定によるエラーも実行して確認します。
1省略時の送料を用意
関数を定義する前に、標準の送料を50へ設定します。
base_shipping = 50定義時に使う値; print(base_shipping)初期値この値をデフォルト引数の式で使います。関数を呼ぶときに毎回この名前を読み直すのか、後で変更して確かめます。
2位置引数とキーワード専用引数
priceは必須、quantityは省略すると1、shippingは名前を指定して渡す引数にします。
def quote(price必須の価格, quantity=1省略時の個数, *, shipping=base_shipping名前で渡す送料と定義時の値):
return price * quantity + shipping受け取った値で計算*の後のshippingはキーワード専用です。base_shippingはこの定義を実行した時点で評価され、省略時の値50が関数に保持されます。
3省略と明示指定
価格100で、個数や送料の渡し方を変えます。
print(quote(100)個数と送料を省略, quote(100, 2)個数を位置で指定, quote(100, 2, shipping=0)送料を名前で指定)結果は150、250、200です。省略した値だけがデフォルトになり、明示的なshipping=0は50へ置き換わりません。
4定義後に元の名前を変える
base_shippingを200へ変更してから、省略する呼出しと明示する呼出しを比べます。
base_shipping = 200元の名前を再代入; print(quote(100)定義時のデフォルトを使用, quote(100, shipping=base_shipping)現在値を明示的に渡す)省略すると以前の50を使って150、明示すると現在の200を渡して300になります。デフォルト式の評価は定義時であり、呼出し時の引数式とは時点が違います。
5名前で指定すると順番を変えられる
三つの引数を名前で指定し、価格を最後に書きます。
quote(shipping=0送料へ0, quantity=2個数へ2, price=100価格へ100)名前に対応する仮引数へ渡るため、結果は200です。関数定義と同じ並びにする必要はありません。ただし通常の位置引数をキーワード引数の後ろへ書くことはできません。
6同じ引数を二度指定するとエラー
priceへ位置で100を渡し、さらにキーワードでも200を渡します。
quote(100, price=200)priceの重複指定priceへ複数の値が渡されるため、TypeErrorが発生します。関数の本体は実行されません。
7一覧と辞書を引数へ展開する
位置引数をタプル、キーワード引数を辞書へ用意します。
positional = (100, 2); options = {"shipping": 0}引数用のコレクション; print(quote(*positional, **options)位置と名前へ展開)*は100と2を位置引数へ展開し、**はshipping=0へ展開します。quote(positional, options)と書くと二つのコレクション自体を渡す別の呼出しになるので、展開記号には意味があります。
8関数の定義で可変長引数を受け取る
今度は定義側で*valuesと**optionsを使います。受け取った組をそのまま返し、中身を確認できるようにします。
def receipt(*values, **options):任意個数をまとめて受け取る
return values, options二つの受取結果定義側の*valuesは位置引数をタプルへ、**optionsはキーワード引数を辞書へまとめます。呼出し側で展開する記号とは働く向きが逆です。
9まとめる側と展開する側を照合
値を直接並べる場合と、先ほどのコレクションを展開する場合を表示します。
print(receipt(100, 2, shipping=0)直接指定してまとめる); print(receipt(*positional, **options)展開してからまとめる); print(receipt()引数なし)どちらも(100, 2)とshipping: 0の組になります。引数なしでは空タプルと空辞書です。可変長で受け取れても、その内容が用途に合うかの検査は関数の責任として残ります。
まとめ
デフォルト値は定義時に評価され、明示的な引数が優先します。
位置・名前・展開の対応を確認し、重複指定を避けます。
操作履歴と解説を振り返れます。
Python 3
base_shipping = 50; print(base_shipping)50
def quote(price, quantity=1, *, shipping=base_shipping):
return price * quantity + shippingprint(quote(100), quote(100, 2), quote(100, 2, shipping=0))150 250 200
base_shipping = 200; print(quote(100), quote(100, shipping=base_shipping))150 300
quote(shipping=0, quantity=2, price=100)200
quote(100, price=200)Traceback (most recent call last): File "<console>", line 1, in <module> TypeError: quote() got multiple values for argument 'price'
positional = (100, 2); options = {"shipping": 0}; print(quote(*positional, **options))200
def receipt(*values, **options):
return values, optionsprint(receipt(100, 2, shipping=0)); print(receipt(*positional, **options)); print(receipt())((100, 2), {'shipping': 0})
((100, 2), {'shipping': 0})
((), {})演習完了