现在我正在研究yield from和await语法之间的区别。从python官方文档中可以看出,yield-from生成器()只是以下代码的语法糖:
for i in generator(): yield i但是我不能在下面的例子中去掉其值。
def accumlate():
# context
accumlator = 0
while True:
next = yield
if next is None:
return accumlator
accumlator += next
def gather(tallies):
while True:
tally = yield from accumlate() # (*)
tallies.append(tally)
def main():
tallies = []
accumlator = gather(tallies)
next(accumlator)
for i in range(4):
accumlator.send(i)
accumlator.send(None)
for i in range(6, 10):
accumlator.send(i)
accumlator.send(None)
print(tallies)
if __name__ == "__main__":
main()我试着只用for-in版本来替换yield from,但它不起作用,因为for-in不能放在tally变量的右边。标有星号的代码的确切描述是什么?
发布于 2019-09-24 16:16:35
@DerteTrdelnik的答案在很大程度上是正确的,只是您根本不需要修改accumlate函数,因为当生成器返回时,生成器会自动使用返回值作为参数引发StopIteration,以构造异常对象。
摘自StopIteration文档
当生成器或协程函数返回时,将引发一个新的
StopIteration实例,并将该函数返回的值用作异常的构造函数的value参数。
因此,您只需要对gather函数进行"desugar“:
def gather(tallies):
while True:
a = accumlate()
a.send(None)
while True:
try:
a.send((yield))
except StopIteration as e:
tallies.append(e.value)
break发布于 2019-09-24 15:32:57
result = yield from generator()不容易被替代,它是如何获得生成器返回值的方法
请参阅https://www.python.org/dev/peps/pep-0380/#proposal
为了模拟一些正在发生的事情而不使用yield,我们必须修改这两个生成器
def accumlate():
# context
accumlator = 0
while True:
next = yield
if next is None:
raise StopIteration(accumlator)
accumlator += next
def gather(tallies):
internal_acc = accumlate()
internal_acc.send(None)
while True:
try:
number_to_add = yield
internal_acc.send(number_to_add)
except StopIteration as e:
internal_acc = accumlate()
internal_acc.send(None)
tallies.append(e.value)accumlate不再返回,但是提升和gather必须尝试除了提升,
在耗尽internal_acc之后,将在except中创建一个新的
正如在pep0380中看到的那样,它有更多的内容,但基本上生成器返回是一个提升,而收益是一个紧凑的捕获。
https://stackoverflow.com/questions/58074236
复制相似问题