least-astonishment - Python オーバーライド - 「驚き最小の原則」と可変のデフォルト引数

Python overload / python / language-design / default-parameters

Pythonを長くいじっていると、誰でも次のような問題に悩まされます。

def foo(a=[]):
    a.append(5)
    return a
>>> foo()
[5]
>>> foo()
[5, 5]
>>> foo()
[5, 5, 5]
>>> foo()
[5, 5, 5, 5]
>>> foo()

Baczekは興味深い例を挙げました。皆さんのほとんどのコメントと、特にUtaalさんのコメントと合わせて、私はさらに詳しく説明しました。

>>> def a():
...     print("a executed")
...     return []
... 
>>>            
>>> def b(x=a()):
...     x.append(5)
...     print(x)
... 
a executed
>>> b()
[5]
>>> b()
[5, 5]

dreftymac



Answer #1

これは実際にはデフォルト値とは何の関係もありませんが、変更可能なデフォルト値を持つ関数を書いたときに、予期せぬ動作として現れることが多いのです。

>>> def foo(a):
    a.append(5)
    print a

>>> a  = [5]
>>> foo(a)
[5, 5]
>>> foo(a)
[5, 5, 5]
>>> foo(a)
[5, 5, 5, 5]
>>> foo(a)
[5, 5, 5, 5, 5]