Pythonのデフォルト引数で注意すること
概要
- 引数のデフォルト値は 1 度だけしか評価されない
- つまり、デフォルト引数で指定した値は、関数実行ごとには初期化されない
- (list や dict のような)変更可能なオブジェクトを指定したい場合は、代わりに None を指定するとよい
現象
関数のデフォルト引数値に、list や dict のように、変更可能(ミュータブル)なオブジェクトを指定したとき、 これは1度しか評価されず、2回目以降はそれを繰り返し使用する。
def f(a, L=[]): L.append(a) return L print(f(1)) # => [1] print(f(2)) # => [1, 2] print(f(3)) # => [1, 2, 3]
この現象は、 Python ドキュメントに 重要な警告 として記載されている。
これは奇妙な現象にも思えるが、オブジェクトに対して変数を割り当てるという Python の視点から解釈すれば納得することもできるだろう (とはいえ、期待する動作ではないのだが。。。)。
対策
一般的に、このような場合は変更可能(ミュータブル)なオブジェクトの代わりに None を使用する。
def f(a, L=None): if L is None: L = [] L.append(a) return L print(f(1)) # => [1] print(f(2)) # => [2] print(f(3)) # => [3]