One way to dodge around the issue of rebinding the class variable is to replace the immutable integer value with an mutable object that contains the number inside it. You can then mutate the object in place.
A simple version of this is to put the number in a one-element list:
class MyClass(object):
next_number = [0]
def __init__(self):
self.number = self.next_number[0]
self.next_number[0] += 1
That works, but it's not very elegant.
A much better approach would be to replace the integer class variable with an iterator returned by the itertools.count function, which will yield successively higher integers each time you call next on it (forever, it's an infinite iterator). At a high level this still works like the list code, since next mutates the iterator, but the exact details are hidden behind the iterator protocol (and the implementation of itertools.count).
class MyClass(object):
number_iter = itertools.count()
def __init__(self):
self.number = next(self.number_iter) # this mutates number_iter by consuming a value
If you needed something a little more complicated, such that itertools didn't provide exactly the right sequence, you could write your own generator function and assign its return value to your class variable. For instance, here's a generator for the Fibonacci sequence:
def fib():
a, b = 0, 1
while True:
a, b = b, a+b
yield a
self.__class__instead? Could you use anEnuminstead?