9

I'm a C# programmer trying to understand some Python code. The code in question is a generator function, and looks like this:

def func():
    oldValue = curValue
    yield
    curValue = oldValue

If I understand this correctly, this will generate a iterable sequence with one member. However, there is no expression after the yield statement. What is such an expression-less statement supposed to yield? Are there any Python idioms that make use of this way of coding?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
John Källén
  • 7,551
  • 31
  • 64

1 Answers1

12

It'll yield None; just like an empty return expression would:

>>> def func():
...     yield
... 
>>> f = func()
>>> next(f) is None
True

You'd use it to pause code. Everything before the yield is run when you first call next() on the generator, everything after the yield is only run when you call next() on it again:

>>> def func():
...     print("Run this first for a while")
...     yield
...     print("Run this last, but only when we want it to")
... 
>>> f = func()
>>> next(f, None)
Run this first for a while
>>> next(f, None)
Run this last, but only when we want it to

I used the two-argument form of next() to ignore the StopIteration exception thrown. The above doesn't care what is yielded, only that the function is paused at that point.

For a practical example, the @contextlib.contextmanager decorator fully expects you to use yield in this manner; you can optionally yield an object to use in the with ... as target. The point is that everything before the yield is run when the context is entered, everything after is run when the context is exited.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • I have so much to learn in python :) Parasite question: Can we implement some sort of check-point system using multiple empty `yield`s? Or is this dangerous? – Tejas Pendse Apr 09 '14 at 11:20
  • You can look at slides here: http://www.dabeaz.com/coroutines/index.html Short answer: yield is very powerful. – x3al Apr 09 '14 at 11:38
  • @x3al: sure, but as `yield` is used here as a statement rather than as an expression (the expression result is ignored) we are not quite in coroutine country just yet. :-) – Martijn Pieters Apr 09 '14 at 11:41
  • Still, the idea of using `yield` as a `goto` on steroids is similar to coroutine "threads". – x3al Apr 09 '14 at 11:45
  • @x3al: I'm sorry but I'm a bit lost... Are you guys commenting on my question? (I think you are, but not I'm sure :) ) – Tejas Pendse Apr 09 '14 at 12:40