python - Why does += behave unexpectedly on lists? -
the +=
operator in python seems operating unexpectedly on lists. can tell me going on here?
class foo: bar = [] def __init__(self,x): self.bar += [x] class foo2: bar = [] def __init__(self,x): self.bar = self.bar + [x] f = foo(1) g = foo(2) print f.bar print g.bar f.bar += [3] print f.bar print g.bar f.bar = f.bar + [4] print f.bar print g.bar f = foo2(1) g = foo2(2) print f.bar print g.bar
output
[1, 2] [1, 2] [1, 2, 3] [1, 2, 3] [1, 2, 3, 4] [1, 2, 3] [1] [2]
foo += bar
seems affect every instance of class, whereas foo = foo + bar
seems behave in way expect things behave.
the +=
operator called "compound assignment operator".
the general answer +=
tries call __iadd__
special method, , if isn't available tries use __add__
instead. issue difference between these special methods.
the __iadd__
special method in-place addition, mutates object acts on. __add__
special method returns new object , used standard +
operator.
so when +=
operator used on object has __iadd__
defined object modified in place. otherwise instead try use plain __add__
, return new object.
that why mutable types lists +=
changes object's value, whereas immutable types tuples, strings , integers new object returned instead (a += b
becomes equivalent a = + b
).
for types support both __iadd__
, __add__
therefore have careful 1 use. a += b
call __iadd__
, mutate a
, whereas a = + b
create new object , assign a
. not same operation!
>>> a1 = a2 = [1, 2] >>> b1 = b2 = [1, 2] >>> a1 += [3] # uses __iadd__, modifies a1 in-place >>> b1 = b1 + [3] # uses __add__, creates new list, assigns b1 >>> a2 [1, 2, 3] # a1 , a2 still same list >>> b2 [1, 2] # whereas b1 changed
for immutable types (where don't have __iadd__
) a += b
, a = + b
equivalent. lets use +=
on immutable types, might seem strange design decision until consider otherwise couldn't use +=
on immutable types numbers!
Comments
Post a Comment