一覧PG-06-2 · 関数の入出力

デフォルト引数・キーワード引数・引数の展開

商品価格・個数・送料の関数を使い、同じ値を複数の書き方で渡します。定義時のデフォルト値と、重複指定によるエラーも実行して確認します。

説明

関数の引数は、位置、名前、省略時の値、コレクションの展開によって渡せます。どの仮引数に何が入るかが決まってから、関数本体が動きます。

商品価格・個数・送料の関数を使い、同じ値を複数の書き方で渡します。定義時のデフォルト値と、重複指定によるエラーも実行して確認します。

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

1
base_shipping = 50; print(base_shipping)
50
2
def quote(price, quantity=1, *, shipping=base_shipping): return price * quantity + shipping
3
print(quote(100), quote(100, 2), quote(100, 2, shipping=0))
150 250 200
4
base_shipping = 200; print(quote(100), quote(100, shipping=base_shipping))
150 300
5
quote(shipping=0, quantity=2, price=100)
200
6
quote(100, price=200)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
TypeError: quote() got multiple values for argument 'price'
7
positional = (100, 2); options = {"shipping": 0}; print(quote(*positional, **options))
200
8
def receipt(*values, **options): return values, options
9
print(receipt(100, 2, shipping=0)); print(receipt(*positional, **options)); print(receipt())
((100, 2), {'shipping': 0})
((100, 2), {'shipping': 0})
((), {})

演習完了