Python

python のデフォルト引数の罠

More than 1 year has passed since last update.

要約

  • デフォルト引数は関数定義時に一度だけ評価される
  • 同じインスタンスが使われてしまうため注意が必要

デフォルト引数に参照系の値を渡すのには罠があるという話です。

def hoge(lst=[]):
    lst.append('hoge')
    print(lst)

hoge()
hoge()

lst はデフォルトで空配列なので、 ['hoge'] が2回表示されると思いますよね。

実行結果
['hoge']
['hoge', 'hoge']

二度目は hoge が2つきます。

理由

先程のコードを少し変えてこうしてみます。

def called():
    print('called!')
    return []

def hoge(lst=called()):
    lst.append('hoge')
    print(lst)

hoge()
hoge()

結果はこうなります。

実行結果
called!
['hoge']
['hoge', 'hoge']

ちなみに hoge() しなくても called は表示されます。

つまり、デフォルト引数の値は関数定義時に一度だけ呼ばれ生成され、関数呼出し時には既に生成された値を使いまわしているようです。

上のように、「[] をデフォルト引数に与えており、引数指定をしなかったすべての関数呼び出しでリストのインスタンスが共有されてしまう」というパターンはよくありそうな気がします。

常識だったらすみません。