2012-03-19 7 views
9

は、次のコードを考えてみます。異なる挙動は.__ iadd__とリスト.__ add__

>>> x = y = [1, 2, 3, 4] 
>>> x = x + [4] 
>>> x 
[1, 2, 3, 4, 4] 
>>> y 
[1, 2, 3, 4] 

なぜ差がこれらの二つがあります:その後、

>>> x = y = [1, 2, 3, 4] 
>>> x += [4] 
>>> x 
[1, 2, 3, 4, 4] 
>>> y 
[1, 2, 3, 4, 4] 

とは、この考えますか?

(はい、これを検索しました)。示されているように__add__は、新しいリストを返し、一方

+4

あなたの最後の声明について興味深いのは、この機能が実際にpythonのドキュメントで説明されているということです:http://docs.python.org/reference/datamodel.html#object.__add__(これらの用語の検索から) – jdi

+3

@ jdl:はい、私はそれを見落としたことを認めます。 –

答えて

20

__iadd__は、リストを変異します。

x += yの式は、最初に__iadd__を呼び出すと、__add__が代入されます(小修正の場合はSvenのコメントを参照してください)。 listには__iadd__があるので、この小さなビットの突然変異マジックを行います。

+1

この正確な振る舞いや、Pythonがどうしてそういったのかを知るには、[python epiphanies talk](http://pyvideo.org/video/613/python-epiphanies)をぜひお勧めしますPyCon 2012.それはあなたに多くの「a ha!」を導きます。瞬間 –

+0

@S Singhあなたの答えが得られたら、回答を受け入れられた答えとして選択し、ワークフローを完了してください。そうでなければ、この質問は未回答として表示されます。 – Nilesh

+1

この回答は少し誤解を招く: '__iadd __()'か '__add __()'が呼び出されたかどうかにかかわらず、代入は常に実行されます。しかし、 'list .__ iadd __()'は単に 'self'を返すだけですので、ターゲット名を現在のスコープにローカルで描画する以外の割り当ては効果がありません。 –

3

最初のものはリストを変更し、2番目のものは名前を再バインドします。