Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python链式屈服形式`_Python_Async Await - Fatal编程技术网

Python链式屈服形式`

Python链式屈服形式`,python,async-await,Python,Async Await,我在阅读python中有关async和await的内容时,看到了以下示例代码: def bottom(): # Returning the yield lets the value that goes up the call stack to come right back # down. return (yield 42) def middle(): return (yield from bottom()) def top(): return (yi

我在阅读python中有关async和await的内容时,看到了以下示例代码:

def bottom():
    # Returning the yield lets the value that goes up the call stack to come right back
    # down.
    return (yield 42)

def middle():
    return (yield from bottom())

def top():
    return (yield from middle())

# Get the generator.
gen = top()
value = next(gen)
print(value)  # Prints '42'.
try:
    value = gen.send(value * 2)
except StopIteration as exc:
    value = exc.value
print(value)  # Prints '84'.
我能理解链式生成器返回42,但我似乎无法理解gen.sendvalue*2和返回84。我本以为最初的nextgen会像下面的实验一样耗尽发电机

def bottom():
    # Returning the yield lets the value that goes up the call stack to come right back
    # down.
    return (yield 42)

def middle():
    return (yield from bottom())

def top():
    return (yield from middle())

# Get the generator.
gen = top()
value = next(gen)
print(value)  # Prints '42'.

value = next(gen)
print(value)

Traceback (most recent call last):
  File "a.py", line 16, in <module>
    value = next(gen)
StopIteration
有人能解释一下吗


PS:这不是一个经过深思熟虑的标题,请有人帮助修复它…

正如@Steven Rumbalski在评论中已经解释的那样:生成器只产生一个值——42。在第二个调用中,迭代器引发StopIteration,它被except _ustopIteration作为exc:捕获。因此,您完全正确,因为最初的nextgen已经耗尽了生成器。在第二个示例中也是如此,但在本例中,您没有捕获StopIteration异常。为了进一步阅读,我将引用PEP380——委托给子生成器的语法

为生成器迭代器添加一个新的send方法,该方法恢复生成器并发送一个值,该值将成为当前产量表达式的结果。send方法返回生成器生成的下一个值,如果生成器退出而不生成另一个值,则会引发StopIteration

那么,为什么要用gen.sendvalue*2返回84?此时value的值仍然是先前调用value=nextgen时的42。因此,您只需返回要发送给迭代器的84。为什么呢

考虑以下简化示例,以便更好地理解该定义的含义。首先,我们只产生一个值。没有回报。这将导致值属性为None的StopIteration为空

生成器中的return expr导致从生成器退出时引发StopIterationexpr

然后,在生成器不产生其他值后返回2。在这种情况下,来自的规则起作用。由于返回值为2,因此StopIteration的value属性为2

现在我们返回收益率1。根据3中的规则,gen.send3的值成为当前产量表达式的结果。但由于生成器已经耗尽,因此会引发StopIteration异常。这导致3作为提升的StopIteration的值


它确实耗尽了迭代器。迭代器硬编码为只返回42。value=gen.sendvalue*2使用StopIteration失败,因为gen已耗尽。在中,从异常值=exc.value设置异常值。异常似乎会保留发送的值。请注意,只有第一个StopIteration似乎包含发送发送的值;随后的尝试只会引发一个简单的停止迭代。
def generator():
    yield 1

gen = generator()
value = next(gen)
print(value)  # Prints '1'.
try:
    value = gen.send(3)
except StopIteration as exc:
    value = exc.value
print(value)  # Prints 'None'.
def generator():
    yield 1
    return 2

gen = generator()
value = next(gen)
print(value)  # Prints '1'.
try:
    value = gen.send(3)
except StopIteration as exc:
    value = exc.value
print(value)  # Prints '2'.
def generator():
    return (yield 1)

gen = generator()
value = next(gen)
print(value)  # Prints '1'.
try:
     value = gen.send(3)
except StopIteration as exc:
    value = exc.value
print(value)  # Prints '3'.