Behavior of += (was Re: [Python-Dev] Customization docs)

Delaney, Timothy tdelaney at avaya.com
Tue Jun 4 19:50:37 EDT 2002


> From: Jeff Epler [mailto:jepler at unpythonic.net]
> 
> On Tue, Jun 04, 2002 at 12:01:56PM -0400, Steve Holden wrote:
> > >>> a = b = [1,2,3]
> > >>> a += [4]
> > >>> a, id(a), b, id(b)
> > ([1, 2, 3, 4], 269472088, [1, 2, 3, 4], 269472088)
> > >>>
> > 
> > Where did the rebinding take place? ISTM that "a" is still 
> bound to the same
> > list, which has been modified in place.
> 
> Sure it rebinds a (just to the same object formerly bound to it) ..
> >>> class X:
> ...     def __setattr__(self, a, v):
> ...         print "rebinding %s, sucker" % a
> ...         self.__dict__[a] = v
> ... 
> >>> x = X() 
> >>> x.a = b = [1,2,3]
> rebinding a, sucker
> >>> x.a += [4]
> rebinding a, sucker
> >>> x.a is b
> True

To put it another way ... (for __iadd__, assume every inplace assignment
method).

__iadd__ must return an object (or None). The result of __iadd__ is rebound
to the original name.

For an object that modifies in place (such as a list), it returns self from
__iadd__.

So there definitely is rebinding going on with every augmented assignment.

The problem is that the rebinding occurs *after* __iadd__ is called, and I
can't see any way to avoid that. Yes, you can refuse to rebind, but any side
effects have already occurred.

Tim Delaney





More information about the Python-list mailing list