A generator function is a Python function containing yield. Calling it returns a generator object rather than immediately running the function. Each iteration resumes execution through the next yield, returns that value, and pauses again. section 11.4
def foo():
yield 1
yield 2
yield 3
Use yield statements to turn an ordinary-looking function into an incremental iterator. section 11.4
g = foo()
for one_item in g:
print(one_item)
Iterate over the returned generator with a for loop; the loop requests values until the generator finishes. section 11.4
When implementing a generator, reason about the following:
- Put the work that produces one result before yield; execution sleeps immediately afterward and resumes when next is requested. section 11.15
- Rely on retained local variables to carry state between iterations; a generator function executes once with a single stack frame. section 11.19
- Use return to exit early, not raise StopIteration; completion raises StopIteration automatically, and a return value is ignored. section 11.17
- Choose generators when a function-shaped operation must break potentially large data into results without overwhelming the system. section 11.17
Stream lines from multiple files
A directory-reading generator can list filenames, combine each with the directory using os.path.join, ignore unreadable files with except OSError, and yield each line. The caller receives one line at a time while the generator retains its position between requests. section 11.14 section 11.15
Generators can also enrich or transform an existing iterable. An elapsed-time generator yields a tuple containing the seconds since the previous iteration and the next item, preserving the previous timestamp across pauses. section 11.18 section 11.19
A generator function is one of three ways to create an iterator, alongside implementing the iterator protocol in a class and using a generator expression. section 11.26











