__iadd__ useless in sub-classed int
Chris Mellon
arkanes at gmail.com
Thu Dec 6 16:19:45 EST 2007
On Dec 6, 2007 3:02 PM, samwyse <samwyse at gmail.com> wrote:
>
> On Dec 6, 1:12 pm, "Diez B. Roggisch" <de... at nospam.web.de> wrote:
> > samwyse schrieb:
> >
> > > For whatever reason, I need an inproved integer. Sounds easy, let's
> > > just subclass int:
> >
> > >>>> class test(int):
> > > pass
> >
> > > Now let's test it:
> >
> > >>>> zed=test(0)
> > >>>> zed.__class__
> > > <class '__main__.test'>
> > >>>> zed
> > > 0
> >
> > > So far, so good. Now let's try incrementing:
> >
> > >>>> zed+=1
> > >>>> zed
> > > 1
> > >>>> zed.__class__
> > > <type 'int'>
> >
> > > WTF??!
> > > Is this a bug or is it the inevitable result of optimizing for the
> > > case where all integers are indistinguishable?
> >
> > There has been a lengthe thread over the semantics of __iadd__ a few
> > weeks ago. It _can_ modify the object in question in-place (something
> > not possible for ints anyway), but it will ALWAYS return a reference
> > which will be set to the left-hand-side.
>
> Thanks! I'd missed that thread, googling found it but it didn't look
> noteworthy at first glance. I've not yet read the entire thread, but
> I did see a reference to PEP 203.
>
> ) So, given the expression:
> )
> ) x += y
> )
> ) The object `x' is loaded, then `y' is added to it, and the
> ) resulting object is stored back in the original place.
>
> That agrees with what I'm seeing, all right. The problem is, the
> resulting object has a different type, which seems to violate the
> spirit of a later paragraph:
>
The phrasing is a little awkward. Instead of "store" say "bound to the
same name as"
> ) Writing the above expression as
> )
> ) <x> <operator>= <y>
> )
> ) is both more readable and less error prone, because it is
> ) instantly obvious to the reader that it is <x> that is being
> ) changed, and not <x> that is being replaced by something almost,
> ) but not quite, entirely unlike <x>.
>
> And that's my complaint. The value in <zed> is being replaced by
> something almost, but not quite, identical to the original value.
> Python's internal implementation of __iadd__ for <int> isn't returning
> <self>, it's returning a new value belonging to the super-class. My
> whole point is overloading <int> was that I'd hoped to avoid having to
> write a bunch of methods to perform in-place modifications. Looks
> like I stuck, however.
>
Remember that in Python, name binding (which is to say, pure
assignment) is never a mutating operation. It's purely internal to the
namespace it occurs in. So even when augmented assignment returns
self, it still results in a normal Python assignment.
You're going to be struggling against the grain trying to implement a
mutable int anyway, you won't be able to make "foo = 10" mutate the
int, and even if you do create one you probably don't want it to
return true for isinstance(foo, int).
More information about the Python-list
mailing list