累算代入文は、二項演算と代入文を組み合わせて一つの文にしたものです:
augmented_assignment_stmt | ::= | target augop expression_list |
augop | ::= | "+=" | "-=" | "*=" | "/=" | "%=" | "**=" |
| ">>=" | "<<=" | "&=" | "^=" | "|=" |
累算代入文は、ターゲット (通常の代入文と違って、アンパックは 起こりません) と式リストを評価し、それら二つの被演算子間で特定の累算 代入型の二項演算を行い、結果をもとのターゲットに代入します。 ターゲットは一度しか評価されません。
x += 1
のような累算代入式は、x = x + 1
のように書き換えて
ほぼ同様の動作にできますが、厳密に等価にはなりません。累算代入の
方では、x
は一度しか評価されません。また、実際の処理として、
可能ならば インプレース (in-place) 演算が実行されます。
これは、代入時に新たなオブジェクトを生成してターゲットに代入するの
ではなく、以前のオブジェクトの内容を変更するということです。
累算代入文で行われる代入は、タプルへの代入や、一文中に複数の ターゲットが存在する場合を除き、通常の代入と同じように扱われます。 同様に、累算代入で行われる二項演算は、場合によって インプレース演算 が行われることを除き、通常の二項演算 と同じです。
属性参照のターゲットの場合、代入前の初期値は getattr() で 取り出され、演算結果は setattr() で代入されます。 二つのメソッドが同じ変数を参照するという必然性はないので注意してください。 例えば:
class A: x = 3 # class variable a = A() a.x += 1 # writes a.x as 4 leaving A.x as 3
のように、getattr() がクラス変数を参照していても、 setattr() はインスタンス変数への書き込みを行ってしまいます。
ご意見やご指摘をお寄せになりたい方は、 このドキュメントについて... をご覧ください。