関数の引数

パラメータと引数の順

C 言語や Java 言語では、パラメータの順番に(実)引数を渡すのが普通ですよね。

/* 定義側 */ 
void func(int a, int b) { ... }
/* 呼出し側 */
func(2, 3);  // a: 2, b: 3

python では、キーワード引数といって、parameter 名をキーワードに使った呼出しができます。 python には optional arguments といって、省略可能な引数(default 値あり)があるので、 どの option を渡すか指定するためにも必要なんですね。

# 定義側
def func0(sub, verb, obj, sep=' ', last='.'):
    return sub + sep + verb + sep + obj + last
# 呼出し側
    print('test0:', func0('This', 'is', 'a pen'))  # 普通に順番に
      # 出力: test0: This is a pen.
    print('test0sep1:', func0('This', 'is', 'a pen', '_'))  # 4番目の引数は sep
      # 出力: test0sep1: This_is_a pen.
    print('test0sep2:', func0('This', 'is', 'a pen', last='!'))  # keyword をつかって last を指定
      # 出力: test0sep1: test0sep2: This is a pen!

で、別に optional arguments 以外の引数も指定できます。

    print('test0key:', func0(obj='a pen', verb='is', sub='This')) # 順番は逆
      # 出力: test0key: This is a pen.

この書き方は dict データ型と親和性が高いので、dict の keyword と値のペアを入れておき、** を使って引数部に展開することもできます。

    dct = {'obj': 'a pen', 'verb': 'is', 'sub': 'This'}
    print('test0dict:', func0(**dct))  # dct の中身を引数部に展開
      # 出力: test0dict: This is a pen.

可変数引数と dict

さらに、呼び出し側が keyword arguments を利用するなら、定義側で個々の parameter を準備せず、 代わりに dict を使ってもいいよねってなります。

こんな感じ。

# 関数定義側
def func1(**args):  # 複数 parameter を args で表現
    sep = args.get('sep', ' ')  # default value は ' '
    last = args.get('sep', '.')  # default value は '.'
    return args['sub'] + sep + args['verb'] + sep + args['obj'] + last

def func2(dct):  # こちらは普通に、dict 一つを引数に持つ関数
    sep = dct.get('sep', ' ')  # default value は ' '
    last = dct.get('sep', '.')  # default value は '.'
    return dct['sub'] + sep + dct['verb'] + sep + dct['obj'] + last

# 呼出し側
    print('test1key:', func1(obj='a pen', verb='is', sub='This'))  # keyword arguments
      # 出力: test1key: This is a pen.
    print('test1dict', func1(**dct))  # dict を使って keyword arguments を展開
      # 出力: test1dict This is a pen.
      
    print('test2key:', func2({'obj': 'a pen', 'verb': 'is', 'sub': 'This'}))  # こちらは引数1つ
      # 出力: test2key: This is a pen.
    print('test2dict:', func2(dct))  # 同じく
      # 出力: test2dict: This is a pen.

**args は、キーワードがあらかじめ決まっていないようなものにも対処できます。 これとは別に、順番に渡された可変数引数を list で受け取るための *args のような書き方もあります。

Read more