重複の可能性:
Pythonの「驚き最小の原則」:可変のデフォルト引数
どうしてこれなの:
class Test:
def __init__(self, items=[]):
self.items=items
これとは異なります:
class Test2:
def __init__(self, items=None):
if items:
self.items=items
else:
self.items = []
それらは同じことをするべきであるように見えます、しかし:
>>>t = Test()
>>>t.items.append("stuff")
>>>t.items
['stuff']
>>>t2 = Test()
>>>t2.items
['stuff']
さて、Test()を使用すると、作成されるリストは1つだけであり、コンストラクターでアイテムを明示的に設定し、クラスの名前空間に配置しないと思っていたにもかかわらず、誰もがそのリストにアクセスしています。しかし、Test2では:
>>>t = Test2()
>>>t.items.append("stuff")
>>>t.items
['stuff']
>>>t2 = Test2()
>>>t2.items
[]
それは私が期待するように機能しています。また、t = Test([])のように、デフォルトで機能させるのではなく、空のリストを使用して明示的に呼び出す場合、テストはインスタンス間でデータを共有しません。
では、デフォルトは動的ではなく、コンパイル時に1回だけ作成されるということですか?これはクラス定義にのみ当てはまり、関数一般には当てはまりませんか、それとも引数リストでデフォルトを使用する場合のより一般的な落とし穴ですか?(回答:関数でも発生します。)
これをリストではなく文字列でテストしたところ、インスタンス間でデータが共有されないという期待どおりの動作が得られたことに注意してください。しかし、それはdictでも起こります。