Alois Mahdal
Alois Mahdal

Reputation: 11243

Returning generator from a function

I'm slowly getting to wrap my head around Python generators.

While it's not a real life problem for now, I'm still wondering why I can't return a generator from a function.

When I define a function with yield, it acts as a generator. But if I define it inside another function and try to return that instead, I get an ordinary function, i.e. not a generator with next method.

In other words, why the give_gen() approach in code below does not work?

#!/usr/bin/python

import time

def gen(d):
    n = 0
    while True:
        n = n + d
        time.sleep(0.5)
        yield n

def give_gen(d):
    def fn():
        n = 0
        while True:
            n = n + d
            time.sleep(0.5)
            yield n
    return fn

if __name__ == '__main__':

    g = give_gen(3)     # does not work
    g = gen(3)          # works well

    while True:
        print g.next()
        # AttributeError: 'function' object has no attribute 'next'
        # in case of give_gen

Why can't I return a generator from a function?

Upvotes: 5

Views: 151

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1121316

A generator function returns a generator only when called. Call fn to create the generator object:

return fn()

or call the returned object:

g = give_gen(3)()

You did call gen(); had you referred to just gen without calling it you'd have a reference to that function.

Upvotes: 7

Related Questions