[Python-Dev] Subclassing int? [Was: Re: [PEP] += on return of function call result]

Beat Bolli bbolli@ymail.ch
Thu, 8 May 2003 22:20:12 +0200


Andrew Koenig wrote:

> > Why can't you do this?
> >       foo =3D log.setdefault(r,'')
> >       foo +=3D "test %d\n" % t

> You can do it, but it's useless!

I got bitten by the same problem some time ago. Please let me explain:

I needed to count words, using a dict, of course. So, in my first
enthusiasm, I wrote:

        count =3D {}
        for word in wordlist:
            count.setdefault(word, 0) +=3D 1

This, as I soon realized, didn't work, exactly because ints are immutable=
.
So I tried a different track. No problem, I thought, in the new Python
object world, the native classes can be subclassed. I imagined I could
enhance the int class with an inc() method, thusly:

	class Counter(int):
	    def inc(self):
                # to be defined
                self +=3D 1??

        count =3D {}
        for word in wordlist:
            count.setdefault(word, Counter()).inc()

As you can see, I have a problem at the comment: how do I access the
inherited int value??? I realized that this also wasn't going to work,
either. I finally used the perhaps idiomatic

        count =3D {}
        for word in wordlist:
            count[word] =3D count.get(word, 0) + 1

which of course is suboptimal, because the lookup is done twice. I decide=
d
not to implement a proper Counter class for memory efficiency reasons. Th=
e
code would have been simple:

        class Counter:
            def __init__(self):
                self.n =3D 0
            def inc(self):
                self.n +=3D 1
            def get(self):
                return self.n

        count =3D {}
        for word in wordlist:
            count.setdefault(word, Counter()).inc()

But to restate the core question: can class Counter be written as a subcl=
ass
of int?

Beat Bolli (please CC: me on replys, I'm not on the list)
--=20
mail: `echo '<bNObolli@ymaSPilAM.ch>' | sed -e 's/[A-S]//g'`
pgp:  0x506A903A; 49D5 794A EA77 F907 764F D89E 304B 93CF 506A 903A
icbm: 47=B0 02' 43.0" N, 07=B0 16' 17.5" E (WGS84)