为什么 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
我四处乱逛,注意到下面的代码产生了一次值,而我期望它 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 afor
or thenext()
builtin) then the result isNone
. Otherwise, ifsend()
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