Reputation: 1304
I want some sort of a global state that maintains the current number, as well as a function to generate the next number.
I can write a generator to give me the next number.
def gen(self, n):
yield n
yield n + 1
but what is a clean way to maintain its state? I do not want to simply have a global variable. Is there a better way to do this? or is that my only option?
I tried to make a class like this:
class Count:
"""
Represents the counter which
generates variables
"""
def __init__(self, curr=0):
"""
:param curr: the current integer
"""
self.curr = curr
def gen(self):
"""
A generator for the next
number
:return: generator
"""
self.curr += 1
yield self.curr
yield self.curr + 1
but this will not work, because every time I create Count(), it will reset my counter which I don't want.
Upvotes: 0
Views: 890
Reputation: 350272
If you want to maintain state across multiple instances of Count
, then use a variable in the class scope, and reference it with the Count.
prefix, like this:
class Count:
curr = 0
def __init__(self, startWith = None):
if startWith is not None: Count.curr = startWith - 1
def gen(self):
while True:
Count.curr += 1
yield Count.curr
Note that if you want to maintain state, the constructor should allow for the possibility to not reset the counter, but leave it untouched.
As a side note, you might be interested in letting the generator generate a never ending series as shown above.
Here is how you could use the above class:
# Get generator that starts with 2
gen = Count(2).gen();
print (next(gen)); # -> 2
print (next(gen)); # -> 3
print (next(gen)); # -> 4
# Get a generator that continues ...
gen2 = Count().gen();
print (next(gen2)); # -> 5
# We can still use the previous generator also:
print (next(gen)); # -> 6
# Start with 0:
gen3 = Count(0).gen();
print (next(gen3)); # -> 0
# Other generators follow suit:
print (next(gen)); # -> 1
print (next(gen2)); # -> 2
Upvotes: 1
Reputation: 60994
Or you can use the next(generator) function.
def num_gen():
n=1
while n:
yield n
n += 1
Then
>>my_gen = num_gen()
>>next(my_gen)
1
>>next(my_gen)
2
And so forth. Whenever a generator yields a value, the state of the generator is stored so that it can resume execution later.
Upvotes: 0
Reputation: 160427
If my understanding is correct, to eliminate the global
counter you could create a closure for you variable and return a function that increments it.
The original function counter
is called only once, consecutive calls simply increment the counter:
def count(n):
c = n
def incr():
nonlocal c
c += 1
print(c)
return c
return incr
count
is initialized with some state n
and incr
references that state in consecutive calls:
>>> f = count(2)
>>> f()
3
>>> f()
4
>>> f()
5
Upvotes: 0