Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens when a Python yield statement has no expression?

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?

like image 756
John Källén Avatar asked Apr 09 '14 10:04

John Källén


People also ask

What is yield expression Python?

What Is Yield In Python? The Yield keyword in Python is similar to a return statement used for returning values or objects in Python. However, there is a slight difference. The yield statement returns a generator object to the one who calls the function which contains yield, instead of simply returning a value.

What happens after yield Python?

The yield statement suspends function's execution and sends a value back to the caller, but retains enough state to enable function to resume where it is left off. When resumed, the function continues execution immediately after the last yield run.

Does yield mean stop Python?

When the Python yield statement is hit, the program suspends function execution and returns the yielded value to the caller. (In contrast, return stops function execution completely.)

How is yield implemented in Python?

yield in Python can be used like the return statement in a function. When done so, the function instead of returning the output, it returns a generator that can be iterated upon. You can then iterate through the generator to extract items. Iterating is done using a for loop or simply using the next() function.


1 Answers

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.

like image 59
Martijn Pieters Avatar answered Nov 04 '22 17:11

Martijn Pieters