なぜこれが機能するのか
>> x, y = (1, 2)
>> print x, y
1 2
しかし、拡張すると構文エラーが発生します..
>> x, y -= (1, 2)
SyntaxError: illegal expression for augmented assignment
別の方法はありますか、私は期待していました:
>> x, y -= (1, 2)
>> print x, y
0 0
複数のターゲットで拡張割り当てステートメントを使用することはできません。
拡張された割り当てのドキュメントを引用する:
1 つのステートメントでのタプルと複数のターゲットへの代入を除いて、拡張代入ステートメントによって行われる代入は、通常の代入と同じ方法で処理されます。同様に、可能なインプレース動作を除いて、増補代入によって実行される二項演算は、通常の二項演算と同じです。
鉱山を強調します。
インプレース拡張割り当ては(各演算子に対応するフックを使用して) からtarget -= expression
に変換され、その操作を複数のターゲットに変換することはサポートされていません。target = target.__isub__(expression)
__i...__
内部的には、拡張代入は二項演算子 ( +
、*
、-
など)の特殊化であり、代入ではありません。実装はこれらの演算子に基づいており、2 項演算子にはオペランドが 2 つしかないため、元の実装提案に複数のターゲットが含まれることはありませんでした。
割り当てを個別に適用するだけです。
x -= 1
y -= 2
または、本当に本当に複雑にしたい場合は、operator
モジュールを使用して組み合わせzip()
に適用operator.isub
します( を介してitertools.starmap()
、タプル割り当てを使用します:
from operator import sub
from itertools import starmap
x, y = starmap(operator.isub, zip((x, y), (1, 2)))
whereisub
は、正しいフックが呼び出され、それをサポートする可変型のインプレース減算を可能にすることを保証します。
または、インプレース操作をサポートしていない型を操作している場合は、ジェネレーター式を使用して十分です。
x, y = (val - delta for val, delta in zip((x, y), (1, 2)))
これx, y = (1, 2)
がシーケンス割り当てです。これは、右側が反復可能なオブジェクトであり、左側が左側を反復するのと同じ数の変数で構成されていることに依存しています。
これは、左側のオペランドでx, y -= (1, 2)
メソッドを呼び出そうとしています。__isub__
インプレース (「拡張」) 代入の性質は、左辺に変数を取り、その値が演算子呼び出しを受け取り、変数がその呼び出しの結果を受け取ることです。Python では、複数のターゲットにインプレース割り当てを配布することはできません。