デフォルト値(この場合はNone)は、関数オブジェクト(この場合はnonbuggy)の.__defaults__に保持されます。
python
1>>> def nonbuggy(arg, result=None):
2... if result is None:
3... result = []
4... result.append(arg)
5... print(result)
6...
7>>> nonbuggy.__defaults__
8(None,)
関数を呼び出すときにresult引数を指定しなかった場合、result = 関数オブジェクトにあるデフォルト値 が実行されるため、その都度、ローカル変数 result に デフォルト値(この場合はNone) が代入されます。
その後、result = [] などで別の値を代入しても、ローカル変数 result が変更されるだけで、関数オブジェクトにあるデフォルト値(この場合はNone)は変更されません。
python
1>>> nonbuggy(1)
2[1]
3>>> nonbuggy.__defaults__
4(None,)
ただし、デフォルト値がリストなどのミュータブルオブジェクト(変更可能なオブジェクト)で、デフォルト値に対して.appendなどを実行した場合、デフォルト値のオブジェクトが変更され、次の関数呼出し時には変更されたデフォルト値が使用されることになります。
デフォルト値を無理矢理ミュータブルオブジェクトに変えて、その挙動を確認できます。
python
1>>> nonbuggy.__defaults__ = (['hoge'],)
2>>> nonbuggy(1)
3['hoge', 1]
4>>> nonbuggy(3)
5['hoge', 1, 3]
6>>> nonbuggy.__defaults__
7(['hoge', 1, 3],)
2020/02/10 19:03
2020/02/10 22:10 編集
2020/02/11 03:29