I recommend that you always put parentheses around a$_{yield}$ expression when you’re doing something with the returned value, as in the above example. The parentheses aren’t always necessary, but it’s easier to always add them instead of having to remember when they’re needed. ( PEP 342 explains the exact rules, which are that a yield -expression must always be parenthesized except when it occurs at the top-level expression on the right-hand side of an assignment. This means you can write$_{val = yield}$ i but have to use parentheses when there’s an operation, as in$_{val = (yield i) + 12}$ .) Values are sent into a generator by calling its send(value) method. This method resumes the generator’s code and the$_{yield}$ expression returns the specified value. If the regular$_{__next__()}$ method is called, the$_{yield}$ returns None . Here’s a simple counter that increments by 1 and allows changing the value of the internal counter. And here’s an example of changing the counter: Because$_{yield}$ will often be returning$_{None}$ , you should always check for this case. Don’t just use its value in expressions unless you’re sure that the send() method will be the only method used to resume your generator function. In addition to$_{send()}$ , there are two other methods on generators: If you need to run cleanup code when a$_{GeneratorExit}$ occurs, I suggest using a$_{try: ... finally:}$ suite instead of catching$_{GeneratorExit}$. The cumulative effect of these changes is to turn generators from one-way producers of information into both pro- ducers and consumers. Generators also become coroutines , a more generalized form of subroutines. Subroutines are entered at one point and exited at another point (the top of the function, and a$_{return}$statement), but coroutines can be entered, exited, and resumed at many different points (the$_{yield}$ statements). 9 • close() raises a$_{GeneratorExit}$ exception inside the generator to terminate the iteration. On receiving this exception, the generator’s code must either raise$_{GeneratorExit}$ or$_{StopIteration}$; catching the exception and doing anything else is illegal and will trigger a$_{RuntimeError}$.$_{close()}$ will also be called by Python’s garbage collector when the generator is garbage-collected. • throw(type, value=None, traceback=None) is used to raise an exception inside the generator; the exception is raised by the$_{yield}$ expression where the generator’s execution is paused. >>> it =counter( 10 ) >>> next(it) 0 >>> next(it) 1 >>> it.send(8) 8 >>> next(it) 9 >>> next(it) Traceback (most recent call last): File "t.py" , line15 , in <module> it.next() StopIteration def counter(maximum): i =0 while i <maximum: val=( yield i) # If value provided, change counter if val is not None : i =val else : i +=1