11

According to the Python documentation the yield keyword can take an "expression_list", but it is optional:

yield_expression ::= "yield" [expression_list]

I can find no examples of such usage, either in the Python docs, in any of the answers to What does the yield keyword do in Python, nor from generally reading around the web.

If yield is used without an expression_list then I guess that the resulting method cannot be useful as a generator, so are there other scenarios where a plain yield might be useful?

asked Mar 5, 2015 at 14:24
1
  • 4
    It can be used in a with statement. See the example in contextlib Commented Mar 5, 2015 at 14:31

2 Answers 2

10

Although they're almost always used as simple generators, yield enables fully-fledged coroutines .

Besides being used to send values out of a generator / co-routine, yield can also receive values, with the effect of coordinating the execution different co-routines. Thus, you don't need expression_list if you only want to coordinate or receive values.

Here's a simple example:

def infini_printer():
 while True:
 received = yield # get the received value into a variable
 print(received)
printer = infini_printer()
printer.next() # returns None, since we didn't specify any expression after yield
printer.send("foo") # prints "foo"
answered Mar 5, 2015 at 14:33
Sign up to request clarification or add additional context in comments.

Comments

4

It works more like how a return with no arguments simply returns None.

>>> def foobar():
... for i in range(10):
... yield
>>>
>>> for token in foobar():
... print(token)
None
None
None
None
None
None
None
None
None
None

Where this is going to be more common is when you are writing coroutines where there is important work you are doing in a function, and the yield point is simply the 'pause' point -- waiting for someone or something to call next or send but you may not have anything of concern to return.

>>> def do_important_work():
...
... do_it = True
... state = 0
... while do_it:
... print(state)
... state += 1
... # do some more important work here ...
... do_it = yield
...
>>> worker = do_important_work()
... 
>>> worker.next()
>>> worker.send(True)
>>> worker.send(True)
>>> worker.send(True)
0
1
2
3

I think yield was simply designed so you were not forced to return a value, just like how return is designed.

answered Mar 5, 2015 at 14:28

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.