Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does a return do when using a "yield from" expression?

I haven't been able to find any examples of return values from the yield from expression. I have tried this simple code, without success:

def return4():
    return 4


def yield_from():
    res = yield from range(4)
    res = yield from return4()


def test_yield_from():
    for x in yield_from():
        print(x)


test_yield_from()

Which produces:

» python test.py 
0
1
2
3
Traceback (most recent call last):
  File "test.py", line 52, in <module>
    test_yield_from()
  File "test.py", line 48, in test_yield_from
    for x in yield_from():
  File "test.py", line 44, in yield_from
    res = yield from return4()
TypeError: 'int' object is not iterable

But I was expecting:

» python test.py 
0
1
2
3
4

Because, as stated in the PEP:

Furthermore, when the iterator is another generator, the subgenerator is allowed to execute a return statement with a value, and that value becomes the value of the yield from expression.

Obviously, I am not getting this explanation. How does a return in a "subgenerator" work with regards to yield from?

like image 592
blueFast Avatar asked Oct 09 '15 10:10

blueFast


People also ask

What does yield return 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.

Can you have yield and return in the same function?

It's allowed in Python 3. x, but is primarily meant to be used with coroutines - you make asynchronous calls to other coroutines using yield coroutine() (or yield from coroutine() , depending on the asynchronous framework you're using), and return whatever you want to return from the coroutine using return value .

What does yield do in a function?

The yield keyword pauses generator function execution and the value of the expression following the yield keyword is returned to the generator's caller. It can be thought of as a generator-based version of the return keyword. yield can only be called directly from the generator function that contains it.

How does yield work in a for loop?

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.


2 Answers

Generators can return a value when they are exhausted:

def my_gen():
    yield 0
    return "done"

g = my_gen()
next(g)
next(g) # raises StopIteration: "done"

The returned value in a yield from statement will be this value. eg.

def yield_from():
    res = yield from my_gen()
    assert res == "done"

By default this value is None. That is res = yield from range(4) will set res as None.

like image 184
Dunes Avatar answered Nov 15 '22 09:11

Dunes


yield from generator is short for

for i in generator:
    yield i

well it's a bit more commplicated than that: https://www.python.org/dev/peps/pep-0380/#formal-semantics .

this will not work well if generator = 4. (your return4() is not a generator. it's a function.)

in order to get what you wand you would just do this:

def yield_from():
    yield from range(4)
    yield 4
like image 27
hiro protagonist Avatar answered Nov 15 '22 08:11

hiro protagonist