为什么 yield 表达式会崩溃?

Why does the yield expression collapse?

我四处乱逛,注意到下面的代码产生了一次值,而我期望它 return 一个生成器对象。

def f():
    yield (yield 1) 
f().next() # returns 1

def g():
    yield (yield (yield 1) 
g().next() # returns 1

我的问题是 yield 表达式的 value 是什么?如果 yield 表达式崩溃,为什么我们允许嵌套 yield 表达式?

The value of the yield expression after resuming depends on the method which resumed the execution. If __next__() is used (typically via either a for or the next() builtin) then the result is None. Otherwise, if send() is used, then the result will be the value passed in to that method.

所以这个:

def f():
    yield (yield 1) 

相当于:

def f():
    x = yield 1
    yield x

在这种情况下(因为您没有使用 generator.send())等同于:

def f():
    yield 1
    yield None

您的代码只查看生成器生成的第一项。如果您改为调用 list() 来使用整个序列,您将看到我所描述的内容:

def f():
    yield (yield 1)

def g():
    yield (yield (yield 1)) 


print(list(f()))
print(list(g()))

输出:

$ python3 yield.py 
[1, None]
[1, None, None]

如果我们手动迭代生成器(如您所用),但 .send() 它的值,那么您可以看到 yield "returns" 这个值:

gen = f()
print(next(gen))
print(gen.send(42))

输出:

$ python3 yield_manual.py 
1
42