Pythonで+ =をオーバーライドすることは可能ですか?
はい、 __iadd__
メソッド。例:
def __iadd__(self, other):
self.number += other.number
return self
上記の回答で正しく与えられていることに加えて、__iadd__
がオーバーライドされると、x += y
操作は__iadd__
メソッドの終わりで終了しないことを明示的に明確にする価値があります。
代わりに、x = x.__iadd__(y)
で終わります。つまり、Pythonは、実装が完了すると、__iadd__
実装の戻り値を、「追加」するオブジェクトに割り当てます。
これは、x += y
操作の左側を変更して、最終的な暗黙のステップが失敗する可能性があることを意味します。リスト内にあるものに追加するときに何が起こるか考えてください:
>>> x[1] += y # x has two items
これで、__iadd__
実装(x[1]
のオブジェクトのメソッド)が誤ってまたは意図的にリストの先頭から最初の項目(x[0]
)を削除した場合、Pythonが__iadd__
メソッドを実行します)戻り値をx[1]
に割り当ててみてください。存在しなくなり(x[0]
になります)、結果はÌndexError
になります。
または、__iadd__
が上記の例のx
の先頭に何かを挿入すると、オブジェクトはx[2]
ではなくx[1]
になり、x[0]
で以前にあったものはx[1]
になり、__iadd__
の戻り値が割り当てられます呼び出し。
何が起きているのか理解していない限り、結果として生じるバグは修正するのが悪夢です。
オーバーロード__iadd__
(自己を忘れないでください!)、__add__
、x + = yはx = x + yのように機能します。 (これは+ =演算子の落とし穴の1つです。)
>>> class A(object):
... def __init__(self, x):
... self.x = x
... def __add__(self, other):
... return A(self.x + other.x)
>>> a = A(42)
>>> b = A(3)
>>> print a.x, b.x
42 3
>>> old_id = id(a)
>>> a += b
>>> print a.x
45
>>> print old_id == id(a)
False
それも 専門家を排除する :
class Resource(object):
class_counter = 0
def __init__(self):
self.id = self.class_counter
self.class_counter += 1
x = Resource()
y = Resource()
どのような値を期待しますかx.id
、y.id
、およびResource.class_counter
持つため?
http://docs.python.org/reference/datamodel.html#emulating-numeric-types
たとえば、ステートメントx + = y(xは__iadd __()メソッドを持つクラスのインスタンス)を実行するには、x .__ iadd __(y)が呼び出されます。