Incrementing a string

Andrew Dalke adalke at
Thu Sep 16 07:49:36 CEST 2004

Phil Frost wrote:
> import string
> class LabelCounter(object):
>     digits = string.lowercase
>     # define other operators as needed; it's a shame this can't inherit from
>     # int and get these for free. It can't do this because all of int's
>     # operators return ints, not LabelCounters.

Try this instead.  As usual with clever solutions, you
probably shouldn't use this in real code.

import string

def fixup(klass):
   for name, meth in inspect.getmembers(klass):
     # Find all the methods except for a few special ones
     # we know won't return integers
     if (callable(meth) and name not in
         ["__class__", "__new__", "__init__", "__str__", "__repr__"]):

       # Need to make a wrapper function (g) for each of these methods.
       # The wrapper function needs to know the original method, which
       # is stored in the newly created scope (f).
       def f(meth = meth):
         def g(self, *args, **kwargs):
           retval = meth(self, *args, **kwargs)
           if isinstance(retval, int):
             return LabelCounter(retval)
           return retval
         return g
       g = f()
       setattr(klass, name, g)  # replace with the wrapped version

class LabelCounter(int):
   digits = string.ascii_lowercase
   def __str__(self):
     letters = []
     i = int(self)
     while i:
       d, m = divmod(i, len(self.digits))
       i = d
     return "".join(letters[::-1]) or self.digits[0]
   __repr__ = __str__

Here it is in use.

 >>> a = LabelCounter(4)
 >>> print a
 >>> print a+1
 >>> print a+10
 >>> print (a+10)/2
 >>> print a
 >>> print a/2
 >>> print a/3
 >>> print a/30
 >>> print a**4

> You can set 'digits' to any sequence at all. Set it to '01' to get
> output in binary, or to ['01','23','45','67','89'] to get base 5 in a
> very confusing notation *g*

I set it to ascii_lowercase since string.lowercase is locale

 >>> import string, locale
 >>> string.lowercase
 >>> locale.setlocale(locale.LC_ALL, "de_DE")
 >>> string.lowercase

OTOH, that might be what you wanted ...

				dalke at

More information about the Python-list mailing list