2

So, here is a python expression:

a = yield from f()

What does it mean? Where can it be used? What kind of object should f be? What will be the value of a after the expression is evaluated?

There are several questions here on stackoverflow about python's yield and yield from but I did not find an answer to this.

I understand the meaning of yield x, y = yield and y = yield x. Even yield from f() is more or less understandable. But a = yield from f() is something unexpected for me.

UPDATE:

B. Barbieri provided correct answer. Still I need to formulate it a little bit differently.

Semantic of the expression a = yield from f() is very similar to a function call: value of a would be what f() returns. But if f() yields anything, the yielded value would be forwarded to "upper level" (you can only write a = yield from f() inside a function, and this will make you function a generator). If after that the "upper level" sends a value back to your generator, the value will be forwarded to f() and the f() will continue.

The yield from allows f() and "upper level" to communicate while your function is running.

I guess now I do understand what this yield from is all about and hope this explanation would be helpful for others.

lesnik
  • 2,507
  • 2
  • 25
  • 24

2 Answers2

4

Here is a very simple example (yield from can only be used inside a function)

def f():
    for i in range(2):
        yield i
    return 3

def g():
    a = yield from f()
    print('a = {}'.format(a))

for item in g():
    print(item)

# output:
# 0
# 1
# a = 3

a is assigned the value which the function f() returns. The generator g yields all the intermediate results.

  • f must be a generator (something that yields).
  • a will simply be assigned the return value of f()
smci
  • 32,567
  • 20
  • 113
  • 146
hiro protagonist
  • 44,693
  • 14
  • 86
  • 111
2

According to the documentation :

  • f should be a generator (which is no surprise)
  • f should return (and not only yield)
  • f should accept value from send using some_var = yield
  • a will recieve the value returned by f

Here's a f example :

def f():
    while 1:
        x = yield
        if next is None:
            return "something"
        do_something_with_recieved_value(x)

Considering a generator g:

l = []
def g():
    while True:
        a = yield from f()
        l.append(a)
  • whenever f returns, the returned value is put into l
  • every value send to g via send will be forwarded to f

Note : you need to start your generator before being able to send it something.

o = g()
next(o)  # Ensure the accumulator is ready to accept values

I have'nt tested everything, don't hesitate to comment if anything is unclear.

B. Barbieri
  • 1,055
  • 13
  • 16