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?
Python provides a generator to create your own iterator function. A generator is a special type of function which does not return a single value, instead, it returns an iterator object with a sequence of values.
Calling a generator function returns a generator object, which is a lazy iterable.
Calling a generator function inside another to generate a function: we can call a generator function inside another generator function by using the yield * operator (or statement). Example 3: In this example, we call a generator function inside another generator function using the yield * statement.
It returns only a single value to the caller, and the code execution stops as soon as it reaches the return statement. When a caller calls the generator function, the first yield is executed, and the function stops. It then returns the generator object to the caller where the value is stored.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With