Search code examples
pythonfunctionnestedgeneratoryield

How to yield results from a nested generator function?


I have a function which yields results as it downloads them. For the purposes of this question, lets say I yield a sting once every second but I want a convenience function to wrap my generator:

import time

def GeneratorFunction(max_val):
    for i in range(0,5):
        time.sleep(1)
        yield "String %d"%i

def SmallGenerator():
    yield GeneratorFunction(3)

for s in SmallGenerator():
    print s

...why doesn't that just print the 5 strings I'm expecting? Instead it appears to return the generator functio:

<generator object GeneratorFunction at 0x020649B8>

How can I get this to yield the strings as a normal generator function would?


Solution

  • Can't believe I missed this; The answer is to simply return the generator function with suitable arguments applied:

    import time
    
    def GeneratorFunction(max_val):
        for i in range(0,max_val):
            time.sleep(1)
            yield "String %d"%i
    
    def SmallGenerator():
        return GeneratorFunction(3) # <-- note the use of return instead of yield
    
    for s in SmallGenerator():
        print s