1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Python の仮引数の種類と渡し方

1
Last updated at Posted at 2026-01-21

Python の仮引数 5 種類について記します。
手元の関数の仮引数の種類がどれか表示する関数 inspect_params() も載せています (inspect.signature() を呼んでいるだけです)。

参考文献 (リンク下のメモは筆者による)

関数を呼ぶときに渡す値は、位置で渡すか、キーワードで渡すかのどちらかで渡します
make_curry(20, 100)  # 1 番目の 20 と、2 番目の 100 を渡す
make_curry(20, meat=100)  # 1 番目の 20 と、キーワード meat の 100 を渡す
make_curry(roux=20, meat=100)  # キーワード roux の 20 と、キーワード meat の 100 を渡す
make_curry(meat=100, roux=20)  # キーワード meat の 100 と、キーワード roux の 20 を渡す

すべての仮引数が位置でもキーワードでも渡せるケース

オブジェクトを調査してくれる標準モジュール inspectinspect.signature() で、ルーと肉と油を受け取る関数 make_curry() のシグネチャ (仮引数情報) を調べます。

import inspect


def inspect_params(func):
    sig = inspect.signature(func)
    print('|name|default|kind|')
    print('|:---|:------|:---|')
    for p in sig.parameters.values():
        default = '-' if p.default is inspect._empty else p.default
        print(f'|{p.name}|{default}|{p.kind}|')


def make_curry(roux, meat, oil=10):
    total = roux + meat + oil
    print(f'{roux=}, {meat=}, {oil=}, {total=}')


inspect_params(make_curry)

調査結果は以下のようになります。

name default kind
roux - POSITIONAL_OR_KEYWORD
meat - POSITIONAL_OR_KEYWORD
oil 10 POSITIONAL_OR_KEYWORD

ルーも肉も油も、位置でもキーワードでも渡せる種類の仮引数です。
例えば肉は、「2 番目の実引数」としても「キーワード meat の実引数」としても渡せます。
したがって、以下のどの呼び出しも有効で同じ結果になります。

make_curry(20, 100)  # ルーも肉も位置で渡せます
make_curry(20, meat=100)  # ルーのみ位置でも渡せます (肉は 2 番目なので肉のみ位置で渡すのは不可)
make_curry(roux=20, meat=100)  # ルーも肉もキーワードでも渡せます
make_curry(meat=100, roux=20)  # キーワードで渡すなら実引数の順番は問いません

# --> roux=20, meat=100, oil=10, total=130

位置でのみ渡せる仮引数があるケース

次に、make_curry() のルーを位置でのみ渡せるようにします。
カレーにルーは必要なので、最初の引数を必ずルーにする決まりにしてもよいと思います。
関数定義の引数リストに / を入れると、それより前の仮引数が位置でのみ渡せるようになります。

def make_curry(roux, /, meat, oil=10):
    total = roux + meat + oil
    print(f'{roux=}, {meat=}, {oil=}, {total=}')
name default kind
roux - POSITIONAL_ONLY
meat - POSITIONAL_OR_KEYWORD
oil 10 POSITIONAL_OR_KEYWORD

こうすると、カレーをつくるときのルーの渡し方がいつも統一される反面、柔軟な呼び出し方はできなくなります。

make_curry(20, 100)  # どちらも位置で渡せます
# --> roux=20, meat=100, oil=10, total=130
make_curry(20, meat=100)  # ルーのみ位置で渡せます (肉は 2 番目なので肉のみ位置で渡すのは不可)
# --> roux=20, meat=100, oil=10, total=130

# make_curry(roux=20, meat=100)  # もはやルーをキーワードで渡すことはできません
# TypeError: make_curry() got some positional-only arguments passed as keyword arguments: 'roux'

キーワードでのみ渡せる仮引数があるケース

次に、最初のルーを除いた引数を逆にキーワードでのみ渡せるようにします。
make_curry(20, 100) と呼び出されているのを見た人が、「カレーだから最初の 20 はルーだろうけど、次の 100 は何を渡しているんだろう? たまねぎ?」となりかねないからです。キーワードを強制すれば、肉と間違っていちごジャムを渡す事故なども起きにくそうです。
関数定義の引数リストに * を入れると、それより後ろの仮引数がキーワードでのみ渡せるようになります。

def make_curry(roux, /, *, meat, oil=10):
    total = roux + meat + oil
    print(f'{roux=}, {meat=}, {oil=}, {total=}')
name default kind
roux - POSITIONAL_ONLY
meat - KEYWORD_ONLY
oil 10 KEYWORD_ONLY

こうするともはや肉を位置で渡すことはできなくなり、必ずキーワード meat= を付けて渡さなければならなくなります。

make_curry(20, meat=100)
# --> roux=20, meat=100, oil=10, total=130

# make_curry(20, 100)  # もはや肉を位置で渡すことはできません
# TypeError: make_curry() takes 1 positional argument but 2 were given

位置でのみ渡せる可変長の仮引数があるケース

カレーに肉以外の具材も自由に入れられるようにしたいということもあると思います。
仮引数に * を付けると、「そこに位置によって何個でも値を渡せる」仮引数になります。

def make_curry(roux, /, meat, oil=10, *darkmatter):
    total = roux + meat + oil + sum(darkmatter)
    print(f'{roux=}, {meat=}, {oil=}, {sum(darkmatter)=}, {total=}')
name default kind
roux - POSITIONAL_ONLY
meat - POSITIONAL_OR_KEYWORD
oil 10 POSITIONAL_OR_KEYWORD
darkmatter - VAR_POSITIONAL

こうすると、以下のように他の具材もぽんぽんカレーに入れることができます。
ただし、他の具材を位置によって渡すため、他の値を渡すときはその手前にある油を必ず位置で渡す必要があります。また、他の具材をキーワードで渡すことはできません。

make_curry(20, 100, 10, 50, 80)
# --> roux=20, meat=100, oil=10, sum(darkmatter)=130, total=260
make_curry(20, 100, 10, *[50, 80])
# --> roux=20, meat=100, oil=10, sum(darkmatter)=130, total=260

# make_curry(20, 100, 10, onion=50, tomato=80)  # ERROR
# make_curry(20, 100, 10, **{'onion': 50, 'tomato': 80})  # ERROR

キーワードでのみ渡せる可変長の仮引数があるケース

他の具材もぽんぽんカレーに入れられるようになったのはいいですが、いくらカレーが何でも合うとはいえ、何が入っているかわからないのは怖いということもあると思います。
そこで仮引数に ** を付けると、「そこにキーワードによって何個でも値を渡せる」仮引数になります。

def make_curry(roux, /, meat, oil=10, **ingredients):
    total = roux + meat + oil + sum(ingredients.values())
    print(f'{roux=}, {meat=}, {oil=}, {ingredients.keys()}={sum(ingredients.values())}, {total=}')
name default kind
roux - POSITIONAL_ONLY
meat - POSITIONAL_OR_KEYWORD
oil 10 POSITIONAL_OR_KEYWORD
ingredients - VAR_KEYWORD

こうすると、以下のように他の具材をキーワードによってぽんぽんカレーに入れることができます。キーワードなしに入れることはできません。

make_curry(20, 100, onion=50, tomato=80)
# --> roux=20, meat=100, oil=10, dict_keys(['onion', 'tomato'])=130, total=260
make_curry(20, 100, **{'onion': 50, 'tomato': 80})
# --> roux=20, meat=100, oil=10, dict_keys(['onion', 'tomato'])=130, total=260
make_curry(20, 100, **{'oil': 10, 'onion': 50, 'tomato': 80})
# --> roux=20, meat=100, oil=10, dict_keys(['onion', 'tomato'])=130, total=260

# make_curry(20, 100, 10, 50, 80)  # ERROR
# make_curry(20, 100, 10, *[50, 80])  # ERROR
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?